mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-10 16:30:07 +00:00
Commuted all of 'Storage' other than 'Tape' to postfix underscores.
This commit is contained in:
parent
5be22e2f8d
commit
0dc2aa6454
@ -51,10 +51,10 @@ class Cartridge {
|
||||
std::vector<uint8_t> data;
|
||||
};
|
||||
|
||||
const std::list<Segment> &get_segments() { return _segments; }
|
||||
const std::list<Segment> &get_segments() { return segments_; }
|
||||
|
||||
protected:
|
||||
std::list<Segment> _segments;
|
||||
std::list<Segment> segments_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ BinaryDump::BinaryDump(const char *file_name)
|
||||
fclose(file);
|
||||
|
||||
// enshrine
|
||||
_segments.emplace_back(
|
||||
segments_.emplace_back(
|
||||
::Storage::Cartridge::Cartridge::Segment::UnknownAddress,
|
||||
::Storage::Cartridge::Cartridge::Segment::UnknownAddress,
|
||||
std::move(contents));
|
||||
|
@ -46,5 +46,5 @@ PRG::PRG(const char *file_name)
|
||||
if(!Storage::Cartridge::Encodings::CommodoreROM::isROM(contents))
|
||||
throw ErrorNotROM;
|
||||
|
||||
_segments.emplace_back(0xa000, 0xa000 + data_length, std::move(contents));
|
||||
segments_.emplace_back(0xa000, 0xa000 + data_length, std::move(contents));
|
||||
}
|
||||
|
@ -13,58 +13,58 @@
|
||||
using namespace Storage;
|
||||
|
||||
DigitalPhaseLockedLoop::DigitalPhaseLockedLoop(int clocks_per_bit, int tolerance, size_t length_of_history) :
|
||||
_clocks_per_bit(clocks_per_bit),
|
||||
_tolerance(tolerance),
|
||||
clocks_per_bit_(clocks_per_bit),
|
||||
tolerance_(tolerance),
|
||||
|
||||
_phase(0),
|
||||
_window_length(clocks_per_bit),
|
||||
phase_(0),
|
||||
window_length_(clocks_per_bit),
|
||||
|
||||
_phase_error_pointer(0)
|
||||
phase_error_pointer_(0)
|
||||
{
|
||||
_phase_error_history.reset(new std::vector<int>(length_of_history, 0));
|
||||
phase_error_history_.reset(new std::vector<int>(length_of_history, 0));
|
||||
}
|
||||
|
||||
void DigitalPhaseLockedLoop::run_for_cycles(int number_of_cycles)
|
||||
{
|
||||
_phase += number_of_cycles;
|
||||
if(_phase >= _window_length)
|
||||
phase_ += number_of_cycles;
|
||||
if(phase_ >= window_length_)
|
||||
{
|
||||
int windows_crossed = _phase / _window_length;
|
||||
int windows_crossed = phase_ / window_length_;
|
||||
|
||||
// check whether this triggers any 0s, if anybody cares
|
||||
if(_delegate)
|
||||
if(delegate_)
|
||||
{
|
||||
if(_window_was_filled) windows_crossed--;
|
||||
if(window_was_filled_) windows_crossed--;
|
||||
for(int c = 0; c < windows_crossed; c++)
|
||||
_delegate->digital_phase_locked_loop_output_bit(0);
|
||||
delegate_->digital_phase_locked_loop_output_bit(0);
|
||||
}
|
||||
|
||||
_window_was_filled = false;
|
||||
_phase %= _window_length;
|
||||
window_was_filled_ = false;
|
||||
phase_ %= window_length_;
|
||||
}
|
||||
}
|
||||
|
||||
void DigitalPhaseLockedLoop::add_pulse()
|
||||
{
|
||||
if(!_window_was_filled)
|
||||
if(!window_was_filled_)
|
||||
{
|
||||
if(_delegate) _delegate->digital_phase_locked_loop_output_bit(1);
|
||||
_window_was_filled = true;
|
||||
post_phase_error(_phase - (_window_length >> 1));
|
||||
if(delegate_) delegate_->digital_phase_locked_loop_output_bit(1);
|
||||
window_was_filled_ = true;
|
||||
post_phase_error(phase_ - (window_length_ >> 1));
|
||||
}
|
||||
}
|
||||
|
||||
void DigitalPhaseLockedLoop::post_phase_error(int error)
|
||||
{
|
||||
// use a simple spring mechanism as a lowpass filter for phase
|
||||
_phase -= (error + 1) >> 1;
|
||||
phase_ -= (error + 1) >> 1;
|
||||
|
||||
// use the average of the last few errors to affect frequency
|
||||
std::vector<int> *phase_error_history = _phase_error_history.get();
|
||||
std::vector<int> *phase_error_history = phase_error_history_.get();
|
||||
size_t phase_error_history_size = phase_error_history->size();
|
||||
|
||||
(*phase_error_history)[_phase_error_pointer] = error;
|
||||
_phase_error_pointer = (_phase_error_pointer + 1)%phase_error_history_size;
|
||||
(*phase_error_history)[phase_error_pointer_] = error;
|
||||
phase_error_pointer_ = (phase_error_pointer_ + 1)%phase_error_history_size;
|
||||
|
||||
int total_error = 0;
|
||||
for(size_t c = 0; c < phase_error_history_size; c++)
|
||||
@ -72,6 +72,6 @@ void DigitalPhaseLockedLoop::post_phase_error(int error)
|
||||
total_error += (*phase_error_history)[c];
|
||||
}
|
||||
int denominator = (int)(phase_error_history_size * 4);
|
||||
_window_length += (total_error + (denominator >> 1)) / denominator;
|
||||
_window_length = std::max(std::min(_window_length, _clocks_per_bit + _tolerance), _clocks_per_bit - _tolerance);
|
||||
window_length_ += (total_error + (denominator >> 1)) / denominator;
|
||||
window_length_ = std::max(std::min(window_length_, clocks_per_bit_ + tolerance_), clocks_per_bit_ - tolerance_);
|
||||
}
|
||||
|
@ -46,22 +46,22 @@ class DigitalPhaseLockedLoop {
|
||||
};
|
||||
void set_delegate(Delegate *delegate)
|
||||
{
|
||||
_delegate = delegate;
|
||||
delegate_ = delegate;
|
||||
}
|
||||
|
||||
private:
|
||||
Delegate *_delegate;
|
||||
Delegate *delegate_;
|
||||
|
||||
void post_phase_error(int error);
|
||||
std::unique_ptr<std::vector<int>> _phase_error_history;
|
||||
size_t _phase_error_pointer;
|
||||
std::unique_ptr<std::vector<int>> phase_error_history_;
|
||||
size_t phase_error_pointer_;
|
||||
|
||||
int _phase;
|
||||
int _window_length;
|
||||
bool _window_was_filled;
|
||||
int phase_;
|
||||
int window_length_;
|
||||
bool window_was_filled_;
|
||||
|
||||
int _clocks_per_bit;
|
||||
int _tolerance;
|
||||
int clocks_per_bit_;
|
||||
int tolerance_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -11,14 +11,14 @@
|
||||
using namespace Storage::Disk;
|
||||
|
||||
Controller::Controller(unsigned int clock_rate, unsigned int clock_rate_multiplier, unsigned int revolutions_per_minute) :
|
||||
_clock_rate(clock_rate * clock_rate_multiplier),
|
||||
_clock_rate_multiplier(clock_rate_multiplier),
|
||||
clock_rate_(clock_rate * clock_rate_multiplier),
|
||||
clock_rate_multiplier_(clock_rate_multiplier),
|
||||
|
||||
TimedEventLoop(clock_rate * clock_rate_multiplier)
|
||||
{
|
||||
_rotational_multiplier.length = 60;
|
||||
_rotational_multiplier.clock_rate = revolutions_per_minute;
|
||||
_rotational_multiplier.simplify();
|
||||
rotational_multiplier_.length = 60;
|
||||
rotational_multiplier_.clock_rate = revolutions_per_minute;
|
||||
rotational_multiplier_.simplify();
|
||||
|
||||
// seed this class with a PLL, any PLL, so that it's safe to assume non-nullptr later
|
||||
Time one;
|
||||
@ -27,38 +27,38 @@ Controller::Controller(unsigned int clock_rate, unsigned int clock_rate_multipli
|
||||
|
||||
void Controller::setup_track()
|
||||
{
|
||||
_track = _drive->get_track();
|
||||
track_ = drive_->get_track();
|
||||
|
||||
Time offset;
|
||||
if(_track && _time_into_track.length > 0)
|
||||
if(track_ && time_into_track_.length > 0)
|
||||
{
|
||||
Time time_found = _track->seek_to(_time_into_track).simplify();
|
||||
offset = (_time_into_track - time_found).simplify();
|
||||
_time_into_track = time_found;
|
||||
Time time_found = track_->seek_to(time_into_track_).simplify();
|
||||
offset = (time_into_track_ - time_found).simplify();
|
||||
time_into_track_ = time_found;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = _time_into_track;
|
||||
_time_into_track.set_zero();
|
||||
offset = time_into_track_;
|
||||
time_into_track_.set_zero();
|
||||
}
|
||||
|
||||
reset_timer_to_offset(offset * _rotational_multiplier);
|
||||
reset_timer_to_offset(offset * rotational_multiplier_);
|
||||
get_next_event();
|
||||
}
|
||||
|
||||
void Controller::run_for_cycles(int number_of_cycles)
|
||||
{
|
||||
if(_drive && _drive->has_disk() && _motor_is_on)
|
||||
if(drive_ && drive_->has_disk() && motor_is_on_)
|
||||
{
|
||||
if(!_track) setup_track();
|
||||
number_of_cycles *= _clock_rate_multiplier;
|
||||
if(!track_) setup_track();
|
||||
number_of_cycles *= clock_rate_multiplier_;
|
||||
while(number_of_cycles)
|
||||
{
|
||||
int cycles_until_next_event = (int)get_cycles_until_next_event();
|
||||
int cycles_to_run_for = std::min(cycles_until_next_event, number_of_cycles);
|
||||
_cycles_since_index_hole += (unsigned int)cycles_to_run_for;
|
||||
cycles_since_index_hole_ += (unsigned int)cycles_to_run_for;
|
||||
number_of_cycles -= cycles_to_run_for;
|
||||
_pll->run_for_cycles(cycles_to_run_for);
|
||||
pll_->run_for_cycles(cycles_to_run_for);
|
||||
TimedEventLoop::run_for_cycles(cycles_to_run_for);
|
||||
}
|
||||
}
|
||||
@ -68,31 +68,31 @@ void Controller::run_for_cycles(int number_of_cycles)
|
||||
|
||||
void Controller::get_next_event()
|
||||
{
|
||||
if(_track)
|
||||
_current_event = _track->get_next_event();
|
||||
if(track_)
|
||||
current_event_ = track_->get_next_event();
|
||||
else
|
||||
{
|
||||
_current_event.length.length = 1;
|
||||
_current_event.length.clock_rate = 1;
|
||||
_current_event.type = Track::Event::IndexHole;
|
||||
current_event_.length.length = 1;
|
||||
current_event_.length.clock_rate = 1;
|
||||
current_event_.type = Track::Event::IndexHole;
|
||||
}
|
||||
|
||||
// divide interval, which is in terms of a rotation of the disk, by rotation speed, and
|
||||
// convert it into revolutions per second
|
||||
set_next_event_time_interval(_current_event.length * _rotational_multiplier);
|
||||
set_next_event_time_interval(current_event_.length * rotational_multiplier_);
|
||||
}
|
||||
|
||||
void Controller::process_next_event()
|
||||
{
|
||||
switch(_current_event.type)
|
||||
switch(current_event_.type)
|
||||
{
|
||||
case Track::Event::FluxTransition:
|
||||
_pll->add_pulse();
|
||||
_time_into_track += _current_event.length;
|
||||
pll_->add_pulse();
|
||||
time_into_track_ += current_event_.length;
|
||||
break;
|
||||
case Track::Event::IndexHole:
|
||||
_cycles_since_index_hole = 0;
|
||||
_time_into_track.set_zero();
|
||||
cycles_since_index_hole_ = 0;
|
||||
time_into_track_.set_zero();
|
||||
process_index_hole();
|
||||
break;
|
||||
}
|
||||
@ -103,57 +103,57 @@ void Controller::process_next_event()
|
||||
|
||||
void Controller::set_expected_bit_length(Time bit_length)
|
||||
{
|
||||
_bit_length = bit_length;
|
||||
bit_length_ = bit_length;
|
||||
|
||||
// this conversion doesn't need to be exact because there's a lot of variation to be taken
|
||||
// account of in rotation speed, air turbulence, etc, so a direct conversion will do
|
||||
int clocks_per_bit = (int)((bit_length.length * _clock_rate) / bit_length.clock_rate);
|
||||
_pll.reset(new DigitalPhaseLockedLoop(clocks_per_bit, clocks_per_bit / 5, 3));
|
||||
_pll->set_delegate(this);
|
||||
int clocks_per_bit = (int)((bit_length.length * clock_rate_) / bit_length.clock_rate);
|
||||
pll_.reset(new DigitalPhaseLockedLoop(clocks_per_bit, clocks_per_bit / 5, 3));
|
||||
pll_->set_delegate(this);
|
||||
}
|
||||
|
||||
void Controller::digital_phase_locked_loop_output_bit(int value)
|
||||
{
|
||||
process_input_bit(value, _cycles_since_index_hole);
|
||||
process_input_bit(value, cycles_since_index_hole_);
|
||||
}
|
||||
|
||||
#pragma mark - Drive actions
|
||||
|
||||
bool Controller::get_is_track_zero()
|
||||
{
|
||||
if(!_drive) return false;
|
||||
return _drive->get_is_track_zero();
|
||||
if(!drive_) return false;
|
||||
return drive_->get_is_track_zero();
|
||||
}
|
||||
|
||||
bool Controller::get_drive_is_ready()
|
||||
{
|
||||
if(!_drive) return false;
|
||||
return _drive->has_disk();
|
||||
if(!drive_) return false;
|
||||
return drive_->has_disk();
|
||||
}
|
||||
|
||||
void Controller::step(int direction)
|
||||
{
|
||||
if(_drive) _drive->step(direction);
|
||||
if(drive_) drive_->step(direction);
|
||||
invalidate_track();
|
||||
}
|
||||
|
||||
void Controller::set_motor_on(bool motor_on)
|
||||
{
|
||||
_motor_is_on = motor_on;
|
||||
motor_is_on_ = motor_on;
|
||||
}
|
||||
|
||||
bool Controller::get_motor_on()
|
||||
{
|
||||
return _motor_is_on;
|
||||
return motor_is_on_;
|
||||
}
|
||||
|
||||
void Controller::set_drive(std::shared_ptr<Drive> drive)
|
||||
{
|
||||
_drive = drive;
|
||||
drive_ = drive;
|
||||
invalidate_track();
|
||||
}
|
||||
|
||||
void Controller::invalidate_track()
|
||||
{
|
||||
_track = nullptr;
|
||||
track_ = nullptr;
|
||||
}
|
||||
|
@ -81,20 +81,20 @@ class Controller: public DigitalPhaseLockedLoop::Delegate, public TimedEventLoop
|
||||
virtual bool get_drive_is_ready();
|
||||
|
||||
private:
|
||||
Time _bit_length;
|
||||
unsigned int _clock_rate;
|
||||
unsigned int _clock_rate_multiplier;
|
||||
Time _rotational_multiplier;
|
||||
Time bit_length_;
|
||||
unsigned int clock_rate_;
|
||||
unsigned int clock_rate_multiplier_;
|
||||
Time rotational_multiplier_;
|
||||
|
||||
std::shared_ptr<DigitalPhaseLockedLoop> _pll;
|
||||
std::shared_ptr<Drive> _drive;
|
||||
std::shared_ptr<Track> _track;
|
||||
unsigned int _cycles_since_index_hole;
|
||||
std::shared_ptr<DigitalPhaseLockedLoop> pll_;
|
||||
std::shared_ptr<Drive> drive_;
|
||||
std::shared_ptr<Track> track_;
|
||||
unsigned int cycles_since_index_hole_;
|
||||
|
||||
inline void get_next_event();
|
||||
Track::Event _current_event;
|
||||
Time _time_into_track;
|
||||
bool _motor_is_on;
|
||||
Track::Event current_event_;
|
||||
Time time_into_track_;
|
||||
bool motor_is_on_;
|
||||
|
||||
void setup_track();
|
||||
};
|
||||
|
@ -12,35 +12,35 @@
|
||||
using namespace Storage::Disk;
|
||||
|
||||
Drive::Drive()
|
||||
: _head_position(0), _head(0) {}
|
||||
: head_position_(0), head_(0) {}
|
||||
|
||||
void Drive::set_disk(std::shared_ptr<Disk> disk)
|
||||
{
|
||||
_disk = disk;
|
||||
disk_ = disk;
|
||||
}
|
||||
|
||||
bool Drive::has_disk()
|
||||
{
|
||||
return (bool)_disk;
|
||||
return (bool)disk_;
|
||||
}
|
||||
|
||||
bool Drive::get_is_track_zero()
|
||||
{
|
||||
return _head_position == 0;
|
||||
return head_position_ == 0;
|
||||
}
|
||||
|
||||
void Drive::step(int direction)
|
||||
{
|
||||
_head_position = std::max(_head_position + direction, 0);
|
||||
head_position_ = std::max(head_position_ + direction, 0);
|
||||
}
|
||||
|
||||
void Drive::set_head(unsigned int head)
|
||||
{
|
||||
_head = head;
|
||||
head_ = head;
|
||||
}
|
||||
|
||||
std::shared_ptr<Track> Drive::get_track()
|
||||
{
|
||||
if(_disk) return _disk->get_track_at_position(_head, (unsigned int)_head_position);
|
||||
if(disk_) return disk_->get_track_at_position(head_, (unsigned int)head_position_);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -47,9 +47,9 @@ class Drive {
|
||||
std::shared_ptr<Track> get_track();
|
||||
|
||||
private:
|
||||
std::shared_ptr<Disk> _disk;
|
||||
int _head_position;
|
||||
unsigned int _head;
|
||||
std::shared_ptr<Disk> disk_;
|
||||
int head_position_;
|
||||
unsigned int head_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@ using namespace Storage::Disk;
|
||||
|
||||
PCMTrack::PCMTrack(std::vector<PCMSegment> segments)
|
||||
{
|
||||
_segments = std::move(segments);
|
||||
segments_ = std::move(segments);
|
||||
fix_length();
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ PCMTrack::PCMTrack(PCMSegment segment)
|
||||
{
|
||||
segment.length_of_a_bit.length = 1;
|
||||
segment.length_of_a_bit.clock_rate = 1;
|
||||
_segments.push_back(std::move(segment));
|
||||
segments_.push_back(std::move(segment));
|
||||
fix_length();
|
||||
}
|
||||
|
||||
@ -29,54 +29,54 @@ PCMTrack::Event PCMTrack::get_next_event()
|
||||
{
|
||||
// find the next 1 in the input stream, keeping count of length as we go, and assuming it's going
|
||||
// to be a flux transition
|
||||
_next_event.type = Track::Event::FluxTransition;
|
||||
_next_event.length.length = 0;
|
||||
while(_segment_pointer < _segments.size())
|
||||
next_event_.type = Track::Event::FluxTransition;
|
||||
next_event_.length.length = 0;
|
||||
while(segment_pointer_ < segments_.size())
|
||||
{
|
||||
unsigned int clock_multiplier = _track_clock_rate / _segments[_segment_pointer].length_of_a_bit.clock_rate;
|
||||
unsigned int bit_length = clock_multiplier * _segments[_segment_pointer].length_of_a_bit.length;
|
||||
unsigned int clock_multiplier = track_clock_rate_ / segments_[segment_pointer_].length_of_a_bit.clock_rate;
|
||||
unsigned int bit_length = clock_multiplier * segments_[segment_pointer_].length_of_a_bit.length;
|
||||
|
||||
const uint8_t *segment_data = &_segments[_segment_pointer].data[0];
|
||||
while(_bit_pointer < _segments[_segment_pointer].number_of_bits)
|
||||
const uint8_t *segment_data = &segments_[segment_pointer_].data[0];
|
||||
while(bit_pointer_ < segments_[segment_pointer_].number_of_bits)
|
||||
{
|
||||
// for timing simplicity, bits are modelled as happening at the end of their window
|
||||
// TODO: should I account for the converse bit ordering? Or can I assume MSB first?
|
||||
int bit = segment_data[_bit_pointer >> 3] & (0x80 >> (_bit_pointer&7));
|
||||
_bit_pointer++;
|
||||
_next_event.length.length += bit_length;
|
||||
int bit = segment_data[bit_pointer_ >> 3] & (0x80 >> (bit_pointer_&7));
|
||||
bit_pointer_++;
|
||||
next_event_.length.length += bit_length;
|
||||
|
||||
if(bit) return _next_event;
|
||||
if(bit) return next_event_;
|
||||
}
|
||||
_bit_pointer = 0;
|
||||
_segment_pointer++;
|
||||
bit_pointer_ = 0;
|
||||
segment_pointer_++;
|
||||
}
|
||||
|
||||
// check whether we actually reached the index hole
|
||||
if(_segment_pointer == _segments.size())
|
||||
if(segment_pointer_ == segments_.size())
|
||||
{
|
||||
_segment_pointer = 0;
|
||||
_next_event.type = Track::Event::IndexHole;
|
||||
segment_pointer_ = 0;
|
||||
next_event_.type = Track::Event::IndexHole;
|
||||
}
|
||||
|
||||
return _next_event;
|
||||
return next_event_;
|
||||
}
|
||||
|
||||
Storage::Time PCMTrack::seek_to(Time time_since_index_hole)
|
||||
{
|
||||
_segment_pointer = 0;
|
||||
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(_next_event.length.clock_rate, time_since_index_hole.clock_rate);
|
||||
time_so_far.clock_rate = NumberTheory::least_common_multiple(next_event_.length.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())
|
||||
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 / _next_event.length.clock_rate;
|
||||
unsigned int bit_length = ((clock_multiplier / _track_clock_rate) / _segments[_segment_pointer].length_of_a_bit.clock_rate) * _segments[_segment_pointer].length_of_a_bit.length;
|
||||
unsigned int time_in_this_segment = bit_length * _segments[_segment_pointer].number_of_bits;
|
||||
unsigned int clock_multiplier = time_so_far.clock_rate / next_event_.length.clock_rate;
|
||||
unsigned int bit_length = ((clock_multiplier / track_clock_rate_) / segments_[segment_pointer_].length_of_a_bit.clock_rate) * segments_[segment_pointer_].length_of_a_bit.length;
|
||||
unsigned int time_in_this_segment = bit_length * 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;
|
||||
@ -86,7 +86,7 @@ Storage::Time PCMTrack::seek_to(Time time_since_index_hole)
|
||||
unsigned int time_found = time_remaining - (time_remaining % bit_length);
|
||||
|
||||
// resolve that into the stateful bit count
|
||||
_bit_pointer = 1 + (time_remaining / bit_length);
|
||||
bit_pointer_ = 1 + (time_remaining / bit_length);
|
||||
|
||||
// update and return the time sought to
|
||||
time_so_far.length += time_found;
|
||||
@ -95,7 +95,7 @@ Storage::Time PCMTrack::seek_to(Time time_since_index_hole)
|
||||
|
||||
// otherwise, accumulate time and keep moving
|
||||
time_so_far.length += time_in_this_segment;
|
||||
_segment_pointer++;
|
||||
segment_pointer_++;
|
||||
}
|
||||
return time_since_index_hole;
|
||||
}
|
||||
@ -103,19 +103,19 @@ Storage::Time PCMTrack::seek_to(Time time_since_index_hole)
|
||||
void PCMTrack::fix_length()
|
||||
{
|
||||
// find the least common multiple of all segment clock rates
|
||||
_track_clock_rate = _segments[0].length_of_a_bit.clock_rate;
|
||||
for(size_t c = 1; c < _segments.size(); c++)
|
||||
track_clock_rate_ = segments_[0].length_of_a_bit.clock_rate;
|
||||
for(size_t c = 1; c < segments_.size(); c++)
|
||||
{
|
||||
_track_clock_rate = NumberTheory::least_common_multiple(_track_clock_rate, _segments[c].length_of_a_bit.clock_rate);
|
||||
track_clock_rate_ = NumberTheory::least_common_multiple(track_clock_rate_, segments_[c].length_of_a_bit.clock_rate);
|
||||
}
|
||||
|
||||
// thereby determine the total length, storing it to next_event as the track-total divisor
|
||||
_next_event.length.clock_rate = 0;
|
||||
for(size_t c = 0; c < _segments.size(); c++)
|
||||
next_event_.length.clock_rate = 0;
|
||||
for(size_t c = 0; c < segments_.size(); c++)
|
||||
{
|
||||
unsigned int multiplier = _track_clock_rate / _segments[c].length_of_a_bit.clock_rate;
|
||||
_next_event.length.clock_rate += _segments[c].length_of_a_bit.length * _segments[c].number_of_bits * multiplier;
|
||||
unsigned int multiplier = track_clock_rate_ / segments_[c].length_of_a_bit.clock_rate;
|
||||
next_event_.length.clock_rate += segments_[c].length_of_a_bit.length * segments_[c].number_of_bits * multiplier;
|
||||
}
|
||||
|
||||
_segment_pointer = _bit_pointer = 0;
|
||||
segment_pointer_ = bit_pointer_ = 0;
|
||||
}
|
||||
|
@ -52,21 +52,21 @@ class PCMTrack: public Track {
|
||||
|
||||
private:
|
||||
// storage for the segments that describe this track
|
||||
std::vector<PCMSegment> _segments;
|
||||
std::vector<PCMSegment> segments_;
|
||||
|
||||
// a helper to determine the overall track clock rate and it's length
|
||||
void fix_length();
|
||||
|
||||
// the event perpetually returned; impliedly contains the length of the entire track
|
||||
// as its clock rate, per the need for everything on a Track to sum to a length of 1
|
||||
PCMTrack::Event _next_event;
|
||||
PCMTrack::Event next_event_;
|
||||
|
||||
// contains the master clock rate
|
||||
unsigned int _track_clock_rate;
|
||||
unsigned int track_clock_rate_;
|
||||
|
||||
// a pointer to the first bit to consider as the next event
|
||||
size_t _segment_pointer;
|
||||
size_t _bit_pointer;
|
||||
size_t segment_pointer_;
|
||||
size_t bit_pointer_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -13,12 +13,12 @@
|
||||
using namespace Storage;
|
||||
|
||||
TimedEventLoop::TimedEventLoop(unsigned int input_clock_rate) :
|
||||
_input_clock_rate(input_clock_rate) {}
|
||||
input_clock_rate_(input_clock_rate) {}
|
||||
|
||||
void TimedEventLoop::run_for_cycles(int number_of_cycles)
|
||||
{
|
||||
_cycles_until_event -= number_of_cycles;
|
||||
while(_cycles_until_event <= 0)
|
||||
cycles_until_event_ -= number_of_cycles;
|
||||
while(cycles_until_event_ <= 0)
|
||||
{
|
||||
process_next_event();
|
||||
}
|
||||
@ -26,13 +26,13 @@ void TimedEventLoop::run_for_cycles(int number_of_cycles)
|
||||
|
||||
unsigned int TimedEventLoop::get_cycles_until_next_event()
|
||||
{
|
||||
return (unsigned int)std::max(_cycles_until_event, 0);
|
||||
return (unsigned int)std::max(cycles_until_event_, 0);
|
||||
}
|
||||
|
||||
void TimedEventLoop::reset_timer()
|
||||
{
|
||||
_subcycles_until_event.set_zero();
|
||||
_cycles_until_event = 0;
|
||||
subcycles_until_event_.set_zero();
|
||||
cycles_until_event_ = 0;
|
||||
}
|
||||
|
||||
void TimedEventLoop::reset_timer_to_offset(Time offset)
|
||||
@ -49,10 +49,10 @@ void TimedEventLoop::jump_to_next_event()
|
||||
void TimedEventLoop::set_next_event_time_interval(Time interval)
|
||||
{
|
||||
// Calculate [interval]*[input clock rate] + [subcycles until this event].
|
||||
int64_t denominator = (int64_t)interval.clock_rate * (int64_t)_subcycles_until_event.clock_rate;
|
||||
int64_t denominator = (int64_t)interval.clock_rate * (int64_t)subcycles_until_event_.clock_rate;
|
||||
int64_t numerator =
|
||||
(int64_t)_subcycles_until_event.clock_rate * (int64_t)_input_clock_rate * (int64_t)interval.length +
|
||||
(int64_t)interval.clock_rate * (int64_t)_subcycles_until_event.length;
|
||||
(int64_t)subcycles_until_event_.clock_rate * (int64_t)input_clock_rate_ * (int64_t)interval.length +
|
||||
(int64_t)interval.clock_rate * (int64_t)subcycles_until_event_.length;
|
||||
|
||||
// Simplify now, to prepare for stuffing into possibly 32-bit quantities
|
||||
int64_t common_divisor = NumberTheory::greatest_common_divisor(numerator % denominator, denominator);
|
||||
@ -61,9 +61,9 @@ void TimedEventLoop::set_next_event_time_interval(Time interval)
|
||||
|
||||
// So this event will fire in the integral number of cycles from now, putting us at the remainder
|
||||
// number of subcycles
|
||||
_cycles_until_event = (int)(numerator / denominator);
|
||||
_subcycles_until_event.length = (unsigned int)(numerator % denominator);
|
||||
_subcycles_until_event.clock_rate = (unsigned int)denominator;
|
||||
cycles_until_event_ = (int)(numerator / denominator);
|
||||
subcycles_until_event_.length = (unsigned int)(numerator % denominator);
|
||||
subcycles_until_event_.clock_rate = (unsigned int)denominator;
|
||||
}
|
||||
|
||||
Time TimedEventLoop::get_time_into_next_event()
|
||||
|
@ -90,10 +90,9 @@ namespace Storage {
|
||||
Time get_time_into_next_event();
|
||||
|
||||
private:
|
||||
unsigned int _input_clock_rate;
|
||||
int _cycles_until_event;
|
||||
Time _subcycles_until_event;
|
||||
Time _event_interval;
|
||||
unsigned int input_clock_rate_;
|
||||
int cycles_until_event_;
|
||||
Time subcycles_until_event_;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user