1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-25 16:31:42 +00:00
CLK/Storage/Disk/Track/PCMTrack.hpp
2024-01-16 23:34:46 -05:00

91 lines
2.9 KiB
C++

//
// PCMTrack.hpp
// Clock Signal
//
// Created by Thomas Harte on 10/07/2016.
// Copyright 2016 Thomas Harte. All rights reserved.
//
#pragma once
#include "Track.hpp"
#include "PCMSegment.hpp"
#include "../../../ClockReceiver/ClockReceiver.hpp"
#include <vector>
namespace Storage::Disk {
/*!
A subclass of @c Track that provides its @c Events by querying a pulse-code modulated record of original
flux detections, with an implied index hole at the very start of the data.
The data may consist of a single @c PCMSegment or of multiple, allowing a PCM-format track to contain
multiple distinct segments of data, each with a separate clock rate.
*/
class PCMTrack: public Track {
public:
/*!
Creates a @c PCMTrack consisting of multiple segments of data, permitting multiple clock rates.
*/
PCMTrack(const std::vector<PCMSegment> &);
/*!
Creates a @c PCMTrack consisting of a single continuous run of data, implying a constant clock rate.
The segment's @c length_of_a_bit will be ignored and therefore need not be filled in.
*/
PCMTrack(const PCMSegment &);
/*!
Copy constructor; required for Tracks in order to support modifiable disks.
*/
PCMTrack(const PCMTrack &);
/*!
Creates a PCMTrack by sampling the original at a rate of @c bits_per_track.
*/
static PCMTrack *resampled_clone(Track *original, size_t bits_per_track);
// as per @c Track
Event get_next_event() final;
float seek_to(float time_since_index_hole) final;
Track *clone() const final;
// Obtains a copy of this track, flattened to a single PCMSegment, which
// consists of @c bits_per_track potential flux transition points.
PCMTrack *resampled_clone(size_t bits_per_track);
bool is_resampled_clone();
/*!
Replaces whatever is currently on the track from @c start_position to @c start_position + segment length
with the contents of @c segment.
This is a well-defined operation only for tracks with a single segment. The new segment will be resampled
to the track's underlying segment, which will be mutated.
@param start_time The time at which this segment begins. Must be in the range [0, 1).
@param segment The PCM segment to add.
@param clamp_to_index_hole If @c true then the new segment will be truncated if it overruns the index hole;
it will otherwise write over the index hole and continue.
*/
void add_segment(const Time &start_time, const PCMSegment &segment, bool clamp_to_index_hole);
private:
/*!
Creates a PCMTrack with a single segment, consisting of @c bits_per_track flux windows,
initialised with no flux events.
*/
PCMTrack(unsigned int bits_per_track);
// storage for the segments that describe this track
std::vector<PCMSegmentEventSource> segment_event_sources_;
// a pointer to the first bit to consider as the next event
std::size_t segment_pointer_;
PCMTrack();
bool is_resampled_clone_ = false;
};
}