From c8e9b30df05a3d2fc2f00a7123692b5c31306a69 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 12 Jul 2026 22:26:29 -0400 Subject: [PATCH] Avoid multiple track resamplings. --- Storage/Disk/Disk.hpp | 2 +- Storage/Disk/DiskImage/DiskImage.hpp | 10 ++++----- .../DiskImage/DiskImageImplementation.hpp | 8 +++---- Storage/Disk/Drive.cpp | 21 ++++++++++--------- Storage/Disk/Drive.hpp | 8 +++---- 5 files changed, 25 insertions(+), 24 deletions(-) diff --git a/Storage/Disk/Disk.hpp b/Storage/Disk/Disk.hpp index b63353fb4..192bde7bc 100644 --- a/Storage/Disk/Disk.hpp +++ b/Storage/Disk/Disk.hpp @@ -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_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. diff --git a/Storage/Disk/DiskImage/DiskImage.hpp b/Storage/Disk/DiskImage/DiskImage.hpp index 55786d046..8c635741f 100644 --- a/Storage/Disk/DiskImage/DiskImage.hpp +++ b/Storage/Disk/DiskImage/DiskImage.hpp @@ -81,10 +81,10 @@ public: }; class DiskImageHolderBase: public Disk { - protected: - std::set unwritten_tracks_; - mutable std::map> cached_tracks_; - std::unique_ptr> update_queue_; +protected: + std::set unwritten_tracks_; + mutable std::map> cached_tracks_; + std::unique_ptr> 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_at_position(Track::Address address) const override; void set_track_at_position(Track::Address address, const std::shared_ptr &track) override; void flush_tracks() override; bool tracks_differ(Track::Address lhs, Track::Address rhs) const override; diff --git a/Storage/Disk/DiskImage/DiskImageImplementation.hpp b/Storage/Disk/DiskImage/DiskImageImplementation.hpp index 3d2cc21d9..7be00b3dd 100644 --- a/Storage/Disk/DiskImage/DiskImageImplementation.hpp +++ b/Storage/Disk/DiskImage/DiskImageImplementation.hpp @@ -61,18 +61,18 @@ void DiskImageHolder::set_track_at_position(Track::Address address, const std } template -Track *DiskImageHolder::track_at_position(Track::Address address) const { +std::shared_ptr DiskImageHolder::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 = disk_image_.track_at_position(canonical_address); if(!track) return nullptr; cached_tracks_[canonical_address] = track; - return track.get(); + return track; } template diff --git a/Storage/Disk/Drive.cpp b/Storage/Disk/Drive.cpp index e00d6f28e..ae5434f67 100644 --- a/Storage/Disk/Drive.cpp +++ b/Storage/Disk/Drive.cpp @@ -38,6 +38,8 @@ Drive::Drive( random_source_ <<= 1; random_source_ |= ((randomiser() - randomiser.min()) >= half_range) ? 1 : 0; } + + unformatted_track_ = std::make_unique(); } 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 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 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) { 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(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(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_; diff --git a/Storage/Disk/Drive.hpp b/Storage/Disk/Drive.hpp index da6b22f3b..5b9093637 100644 --- a/Storage/Disk/Drive.hpp +++ b/Storage/Disk/Drive.hpp @@ -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 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_; - UnformattedTrack unformatted_track_; - Track *track_ = nullptr; + std::shared_ptr unformatted_track_; + std::shared_ptr 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 get_track(); /*! Attempts to set @c track as the track underneath the current head at the location now stepped to.