Avoid multiple track resamplings.

This commit is contained in:
Thomas Harte committed 2026-07-12 22:26:29 -04:00
1 parent 9e5db43081
commit c8e9b30df0
5 files changed
+25 -24

No files matched your search

+1 -1
View File
@@ -43,7 +43,7 @@ public:
@returns the @c Track at @c position underneath @c head if there are any detectable events there;
returns @c nullptr otherwise.
*/
virtual Track *track_at_position(Track::Address) const = 0;
virtual std::shared_ptr<Track> track_at_position(Track::Address) const = 0;
/*!
Replaces the Track at position @c position underneath @c head with @c track. Ignored if this disk is read-only.
+5 -5
View File
@@ -81,10 +81,10 @@ public:
};
class DiskImageHolderBase: public Disk {
protected:
std::set<Track::Address> unwritten_tracks_;
mutable std::map<Track::Address, std::shared_ptr<Track>> cached_tracks_;
std::unique_ptr<Concurrency::AsyncTaskQueue<true>> update_queue_;
protected:
std::set<Track::Address> unwritten_tracks_;
mutable std::map<Track::Address, std::shared_ptr<Track>> cached_tracks_;
std::unique_ptr<Concurrency::AsyncTaskQueue<true>> update_queue_;
};
/*!
@@ -104,7 +104,7 @@ public:
HeadPosition maximum_head_position() const override;
int head_count() const override;
Track *track_at_position(Track::Address address) const override;
std::shared_ptr<Track> track_at_position(Track::Address address) const override;
void set_track_at_position(Track::Address address, const std::shared_ptr<Track> &track) override;
void flush_tracks() override;
bool tracks_differ(Track::Address lhs, Track::Address rhs) const override;
@@ -61,18 +61,18 @@ void DiskImageHolder<T>::set_track_at_position(Track::Address address, const std
}
template <typename T>
Track *DiskImageHolder<T>::track_at_position(Track::Address address) const {
std::shared_ptr<Track> DiskImageHolder<T>::track_at_position(const Track::Address address) const {
if(address.head >= head_count()) return nullptr;
if(address.position >= maximum_head_position()) return nullptr;
const auto canonical_address = disk_image_.canonical_address(address);
auto cached_track = cached_tracks_.find(canonical_address);
if(cached_track != cached_tracks_.end()) return cached_track->second.get();
const auto cached_track = cached_tracks_.find(canonical_address);
if(cached_track != cached_tracks_.end()) return cached_track->second;
std::shared_ptr<Track> track = disk_image_.track_at_position(canonical_address);
if(!track) return nullptr;
cached_tracks_[canonical_address] = track;
return track.get();
return track;
}
template <typename T>
+11 -10
View File
@@ -38,6 +38,8 @@ Drive::Drive(
random_source_ <<= 1;
random_source_ |= ((randomiser() - randomiser.min()) >= half_range) ? 1 : 0;
}
unformatted_track_ = std::make_unique<UnformattedTrack>();
}
Drive::Drive(
@@ -122,7 +124,7 @@ void Drive::step(const HeadPosition offset) {
did_step(head_position_);
}
Track *Drive::step_to(const HeadPosition offset) {
std::shared_ptr<Track> Drive::step_to(const HeadPosition offset) {
HeadPosition old_head_position = head_position_;
head_position_ = std::max(offset, HeadPosition(0));
@@ -369,7 +371,7 @@ void Drive::process_next_event() {
// MARK: - Track management
Track *Drive::get_track() {
std::shared_ptr<Track> Drive::get_track() {
if(disk_) return disk_->track_at_position(Track::Address(head_, head_position_));
return nullptr;
}
@@ -381,7 +383,7 @@ void Drive::set_track(const std::shared_ptr<Track> &track) {
void Drive::setup_track() {
track_ = get_track();
if(!track_) {
track_ = &unformatted_track_;
track_ = unformatted_track_;
}
float offset = 0.0f;
@@ -454,18 +456,17 @@ void Drive::end_writing() {
//
// "High" is defined as: two samples per clock relative to an idiomatic
// 8Mhz disk controller and 300RPM disk speed.
const size_t high_resolution_track_rate = 3200000;
const size_t high_resolution_track_rate = 3'200'000;
if(!is_reading_) {
is_reading_ = true;
if(!patched_track_) {
// Avoid creating a new patched track if this one is already patched
// patched_track_ = dynamic_cast<PCMTrack *>(track_);
// if(!patched_track_ || !patched_track_->is_resampled_clone()) {
Track *const tr = track_;
patched_track_.reset(PCMTrack::resampled_clone(tr, high_resolution_track_rate));
// }
// Avoid creating a new patched track if this one is already patched.
patched_track_ = std::dynamic_pointer_cast<PCMTrack>(track_);
if(!patched_track_ || !patched_track_->is_resampled_clone()) {
patched_track_.reset(PCMTrack::resampled_clone(track_.get(), high_resolution_track_rate));
}
}
patched_track_->add_segment(write_start_time_, write_segment_, clamp_writing_to_index_hole_);
cycles_since_index_hole_ %= cycles_per_revolution_;
+4 -4
View File
@@ -182,7 +182,7 @@ public:
It's for the benefit of user-optional fast-loading mechanisms **ONLY**.
*/
Track *step_to(HeadPosition offset);
std::shared_ptr<Track> step_to(HeadPosition offset);
/*!
Alters the rotational velocity of this drive.
@@ -217,8 +217,8 @@ private:
// Drives contain an entire disk; from that a certain track
// will be currently under the head.
std::shared_ptr<Disk> disk_;
UnformattedTrack unformatted_track_;
Track *track_ = nullptr;
std::shared_ptr<UnformattedTrack> unformatted_track_;
std::shared_ptr<Track> track_ = nullptr;
bool has_disk_ = false;
// Contains the multiplier that converts between track-relative lengths
@@ -283,7 +283,7 @@ private:
/*!
@returns the track underneath the current head at the location now stepped to.
*/
Track *get_track();
std::shared_ptr<Track> get_track();
/*!
Attempts to set @c track as the track underneath the current head at the location now stepped to.