mirror of
https://github.com/TomHarte/CLK.git
synced 2024-08-20 13:29:27 +00:00
Factored out the PCM track since it's going to be a useful construct for almost every file format. Documented it a little better.
This commit is contained in:
parent
66895d3ac7
commit
1e9eedc314
@ -44,6 +44,7 @@
|
|||||||
4B92EACA1B7C112B00246143 /* 6502TimingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92EAC91B7C112B00246143 /* 6502TimingTests.swift */; };
|
4B92EACA1B7C112B00246143 /* 6502TimingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92EAC91B7C112B00246143 /* 6502TimingTests.swift */; };
|
||||||
4BAB62AD1D3272D200DF5BA0 /* Disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB62AB1D3272D200DF5BA0 /* Disk.cpp */; };
|
4BAB62AD1D3272D200DF5BA0 /* Disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB62AB1D3272D200DF5BA0 /* Disk.cpp */; };
|
||||||
4BAB62B51D327F7E00DF5BA0 /* G64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB62B31D327F7E00DF5BA0 /* G64.cpp */; };
|
4BAB62B51D327F7E00DF5BA0 /* G64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB62B31D327F7E00DF5BA0 /* G64.cpp */; };
|
||||||
|
4BAB62B81D3302CA00DF5BA0 /* PCMTrack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAB62B61D3302CA00DF5BA0 /* PCMTrack.cpp */; };
|
||||||
4BB298EE1B587D8400A49093 /* 6502_functional_test.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E01B587D8300A49093 /* 6502_functional_test.bin */; };
|
4BB298EE1B587D8400A49093 /* 6502_functional_test.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E01B587D8300A49093 /* 6502_functional_test.bin */; };
|
||||||
4BB298EF1B587D8400A49093 /* AllSuiteA.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E11B587D8300A49093 /* AllSuiteA.bin */; };
|
4BB298EF1B587D8400A49093 /* AllSuiteA.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E11B587D8300A49093 /* AllSuiteA.bin */; };
|
||||||
4BB298F11B587D8400A49093 /* start in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E51B587D8300A49093 /* start */; };
|
4BB298F11B587D8400A49093 /* start in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E51B587D8300A49093 /* start */; };
|
||||||
@ -422,6 +423,8 @@
|
|||||||
4BAB62AE1D32730D00DF5BA0 /* Storage.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Storage.hpp; sourceTree = "<group>"; };
|
4BAB62AE1D32730D00DF5BA0 /* Storage.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Storage.hpp; sourceTree = "<group>"; };
|
||||||
4BAB62B31D327F7E00DF5BA0 /* G64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = G64.cpp; sourceTree = "<group>"; };
|
4BAB62B31D327F7E00DF5BA0 /* G64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = G64.cpp; sourceTree = "<group>"; };
|
||||||
4BAB62B41D327F7E00DF5BA0 /* G64.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = G64.hpp; sourceTree = "<group>"; };
|
4BAB62B41D327F7E00DF5BA0 /* G64.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = G64.hpp; sourceTree = "<group>"; };
|
||||||
|
4BAB62B61D3302CA00DF5BA0 /* PCMTrack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCMTrack.cpp; sourceTree = "<group>"; };
|
||||||
|
4BAB62B71D3302CA00DF5BA0 /* PCMTrack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = PCMTrack.hpp; sourceTree = "<group>"; };
|
||||||
4BB297E01B587D8300A49093 /* 6502_functional_test.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = 6502_functional_test.bin; sourceTree = "<group>"; };
|
4BB297E01B587D8300A49093 /* 6502_functional_test.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = 6502_functional_test.bin; sourceTree = "<group>"; };
|
||||||
4BB297E11B587D8300A49093 /* AllSuiteA.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = AllSuiteA.bin; sourceTree = "<group>"; };
|
4BB297E11B587D8300A49093 /* AllSuiteA.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = AllSuiteA.bin; sourceTree = "<group>"; };
|
||||||
4BB297E51B587D8300A49093 /* start */ = {isa = PBXFileReference; lastKnownFileType = file; path = " start"; sourceTree = "<group>"; };
|
4BB297E51B587D8300A49093 /* start */ = {isa = PBXFileReference; lastKnownFileType = file; path = " start"; sourceTree = "<group>"; };
|
||||||
@ -984,6 +987,8 @@
|
|||||||
4BAB62B21D327F7E00DF5BA0 /* Formats */,
|
4BAB62B21D327F7E00DF5BA0 /* Formats */,
|
||||||
4BAB62AB1D3272D200DF5BA0 /* Disk.cpp */,
|
4BAB62AB1D3272D200DF5BA0 /* Disk.cpp */,
|
||||||
4BAB62AC1D3272D200DF5BA0 /* Disk.hpp */,
|
4BAB62AC1D3272D200DF5BA0 /* Disk.hpp */,
|
||||||
|
4BAB62B61D3302CA00DF5BA0 /* PCMTrack.cpp */,
|
||||||
|
4BAB62B71D3302CA00DF5BA0 /* PCMTrack.hpp */,
|
||||||
);
|
);
|
||||||
path = Disk;
|
path = Disk;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1869,6 +1874,7 @@
|
|||||||
4B4DC8281D2C2470003C5BF8 /* C1540.cpp in Sources */,
|
4B4DC8281D2C2470003C5BF8 /* C1540.cpp in Sources */,
|
||||||
4B1E85751D170228001EF87D /* Typer.cpp in Sources */,
|
4B1E85751D170228001EF87D /* Typer.cpp in Sources */,
|
||||||
4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */,
|
4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */,
|
||||||
|
4BAB62B81D3302CA00DF5BA0 /* PCMTrack.cpp in Sources */,
|
||||||
4B69FB3D1C4D908A00B5F0AA /* Tape.cpp in Sources */,
|
4B69FB3D1C4D908A00B5F0AA /* Tape.cpp in Sources */,
|
||||||
4B55CE5D1C3B7D6F0093A61B /* CSOpenGLView.m in Sources */,
|
4B55CE5D1C3B7D6F0093A61B /* CSOpenGLView.m in Sources */,
|
||||||
4B2A53A31D117D36003C6002 /* CSVic20.mm in Sources */,
|
4B2A53A31D117D36003C6002 /* CSVic20.mm in Sources */,
|
||||||
|
@ -22,6 +22,13 @@ namespace Storage {
|
|||||||
*/
|
*/
|
||||||
class Track {
|
class Track {
|
||||||
public:
|
public:
|
||||||
|
/*!
|
||||||
|
Describes a detectable track event — either a flux transition or the passing of the index hole,
|
||||||
|
along with the length of time between the previous event and its occurance.
|
||||||
|
|
||||||
|
The sum of all lengths of time across an entire track should be 1 — if an event is said to be
|
||||||
|
1/3 away then that means 1/3 of a rotation.
|
||||||
|
*/
|
||||||
struct Event {
|
struct Event {
|
||||||
enum {
|
enum {
|
||||||
IndexHole, FluxTransition
|
IndexHole, FluxTransition
|
||||||
@ -29,6 +36,9 @@ class Track {
|
|||||||
Time length;
|
Time length;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,6 +8,9 @@
|
|||||||
|
|
||||||
#include "G64.hpp"
|
#include "G64.hpp"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "../PCMTrack.hpp"
|
||||||
|
|
||||||
using namespace Storage;
|
using namespace Storage;
|
||||||
|
|
||||||
G64::G64(const char *file_name)
|
G64::G64(const char *file_name)
|
||||||
@ -147,96 +150,3 @@ std::shared_ptr<Track> G64::get_track_at_position(unsigned int position)
|
|||||||
|
|
||||||
return resulting_track;
|
return resulting_track;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - PCMTrack
|
|
||||||
|
|
||||||
unsigned int greatest_common_divisor(unsigned int a, unsigned int b)
|
|
||||||
{
|
|
||||||
if(a < b)
|
|
||||||
{
|
|
||||||
unsigned int swap = b;
|
|
||||||
b = a;
|
|
||||||
a = swap;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
if(!a) return b;
|
|
||||||
if(!b) return a;
|
|
||||||
|
|
||||||
unsigned int remainder = a%b;
|
|
||||||
a = b;
|
|
||||||
b = remainder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int least_common_multiple(unsigned int a, unsigned int b)
|
|
||||||
{
|
|
||||||
unsigned int gcd = greatest_common_divisor(a, b);
|
|
||||||
return (a*b) / gcd;
|
|
||||||
}
|
|
||||||
|
|
||||||
PCMTrack::PCMTrack(std::vector<PCMSegment> segments)
|
|
||||||
{
|
|
||||||
_segments = std::move(segments);
|
|
||||||
fix_length();
|
|
||||||
}
|
|
||||||
|
|
||||||
PCMTrack::PCMTrack(PCMSegment segment)
|
|
||||||
{
|
|
||||||
_segments.push_back(std::move(segment));
|
|
||||||
fix_length();
|
|
||||||
}
|
|
||||||
|
|
||||||
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())
|
|
||||||
{
|
|
||||||
unsigned int clock_multiplier = _track_clock_rate / _segments[_segment_pointer].duration.clock_rate;
|
|
||||||
const uint8_t *segment_data = _segments[_segment_pointer].data.get();
|
|
||||||
while(_bit_pointer < _segments[_segment_pointer].duration.length)
|
|
||||||
{
|
|
||||||
// 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 += clock_multiplier;
|
|
||||||
|
|
||||||
if(bit) return _next_event;
|
|
||||||
}
|
|
||||||
_bit_pointer = 0;
|
|
||||||
_segment_pointer++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check whether we actually reached the index hole
|
|
||||||
if(_segment_pointer == _segments.size())
|
|
||||||
{
|
|
||||||
_segment_pointer = 0;
|
|
||||||
_next_event.type = Track::Event::IndexHole;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _next_event;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PCMTrack::fix_length()
|
|
||||||
{
|
|
||||||
// find the least common multiple of all segment clock rates
|
|
||||||
_track_clock_rate = _segments[0].duration.clock_rate;
|
|
||||||
for(size_t c = 1; c < _segments.size(); c++)
|
|
||||||
{
|
|
||||||
_track_clock_rate = least_common_multiple(_track_clock_rate, _segments[c].duration.clock_rate);
|
|
||||||
}
|
|
||||||
|
|
||||||
// therby determine the total length, storing it to next_event as the divisor
|
|
||||||
_next_event.length.clock_rate = 0;
|
|
||||||
for(size_t c = 0; c < _segments.size(); c++)
|
|
||||||
{
|
|
||||||
unsigned int multiplier = _track_clock_rate / _segments[c].duration.clock_rate;
|
|
||||||
_next_event.length.clock_rate += _segments[c].duration.length * multiplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
_segment_pointer = _bit_pointer = 0;
|
|
||||||
}
|
|
||||||
|
@ -10,41 +10,9 @@
|
|||||||
#define G64_hpp
|
#define G64_hpp
|
||||||
|
|
||||||
#include "../Disk.hpp"
|
#include "../Disk.hpp"
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
|
|
||||||
struct PCMSegment {
|
|
||||||
Time duration;
|
|
||||||
std::unique_ptr<uint8_t> data;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PCMTrack: public Track {
|
|
||||||
public:
|
|
||||||
PCMTrack(std::vector<PCMSegment> segments);
|
|
||||||
PCMTrack(PCMSegment segment);
|
|
||||||
|
|
||||||
virtual Event get_next_event();
|
|
||||||
|
|
||||||
private:
|
|
||||||
// storage for the segments that describe this track
|
|
||||||
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;
|
|
||||||
|
|
||||||
// contains the master 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;
|
|
||||||
};
|
|
||||||
|
|
||||||
class G64: public Disk {
|
class G64: public Disk {
|
||||||
public:
|
public:
|
||||||
G64(const char *file_name);
|
G64(const char *file_name);
|
||||||
|
102
Storage/Disk/PCMTrack.cpp
Normal file
102
Storage/Disk/PCMTrack.cpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
//
|
||||||
|
// PCMTrack.cpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 10/07/2016.
|
||||||
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "PCMTrack.hpp"
|
||||||
|
|
||||||
|
using namespace Storage;
|
||||||
|
|
||||||
|
unsigned int greatest_common_divisor(unsigned int a, unsigned int b)
|
||||||
|
{
|
||||||
|
if(a < b)
|
||||||
|
{
|
||||||
|
unsigned int swap = b;
|
||||||
|
b = a;
|
||||||
|
a = swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
if(!a) return b;
|
||||||
|
if(!b) return a;
|
||||||
|
|
||||||
|
unsigned int remainder = a%b;
|
||||||
|
a = b;
|
||||||
|
b = remainder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int least_common_multiple(unsigned int a, unsigned int b)
|
||||||
|
{
|
||||||
|
unsigned int gcd = greatest_common_divisor(a, b);
|
||||||
|
return (a*b) / gcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
PCMTrack::PCMTrack(std::vector<PCMSegment> segments)
|
||||||
|
{
|
||||||
|
_segments = std::move(segments);
|
||||||
|
fix_length();
|
||||||
|
}
|
||||||
|
|
||||||
|
PCMTrack::PCMTrack(PCMSegment segment)
|
||||||
|
{
|
||||||
|
_segments.push_back(std::move(segment));
|
||||||
|
fix_length();
|
||||||
|
}
|
||||||
|
|
||||||
|
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())
|
||||||
|
{
|
||||||
|
unsigned int clock_multiplier = _track_clock_rate / _segments[_segment_pointer].duration.clock_rate;
|
||||||
|
const uint8_t *segment_data = _segments[_segment_pointer].data.get();
|
||||||
|
while(_bit_pointer < _segments[_segment_pointer].duration.length)
|
||||||
|
{
|
||||||
|
// 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 += clock_multiplier;
|
||||||
|
|
||||||
|
if(bit) return _next_event;
|
||||||
|
}
|
||||||
|
_bit_pointer = 0;
|
||||||
|
_segment_pointer++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check whether we actually reached the index hole
|
||||||
|
if(_segment_pointer == _segments.size())
|
||||||
|
{
|
||||||
|
_segment_pointer = 0;
|
||||||
|
_next_event.type = Track::Event::IndexHole;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _next_event;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PCMTrack::fix_length()
|
||||||
|
{
|
||||||
|
// find the least common multiple of all segment clock rates
|
||||||
|
_track_clock_rate = _segments[0].duration.clock_rate;
|
||||||
|
for(size_t c = 1; c < _segments.size(); c++)
|
||||||
|
{
|
||||||
|
_track_clock_rate = least_common_multiple(_track_clock_rate, _segments[c].duration.clock_rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
// therby determine the total length, storing it to next_event as the divisor
|
||||||
|
_next_event.length.clock_rate = 0;
|
||||||
|
for(size_t c = 0; c < _segments.size(); c++)
|
||||||
|
{
|
||||||
|
unsigned int multiplier = _track_clock_rate / _segments[c].duration.clock_rate;
|
||||||
|
_next_event.length.clock_rate += _segments[c].duration.length * multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
_segment_pointer = _bit_pointer = 0;
|
||||||
|
}
|
80
Storage/Disk/PCMTrack.hpp
Normal file
80
Storage/Disk/PCMTrack.hpp
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
//
|
||||||
|
// PCMTrack.hpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 10/07/2016.
|
||||||
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef PCMTrack_hpp
|
||||||
|
#define PCMTrack_hpp
|
||||||
|
|
||||||
|
#include "Disk.hpp"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace Storage {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
A segment of PCM-sampled data. The clock rate in the duration is taken to be relative to all other
|
||||||
|
segments that comprise a track rather than absolute, and the length is taken to be the number of
|
||||||
|
bits from @c data that are actually present.
|
||||||
|
|
||||||
|
Bits from each byte are taken MSB to LSB.
|
||||||
|
|
||||||
|
Actual segment lengths will be calculated such that all segments that comprise a track exactly fill the track.
|
||||||
|
|
||||||
|
So the segment for a track with only a single segment may supply any clock rate other than 0. It will exactly
|
||||||
|
fill the track, so if it has 7 samples then there will be at most a flux transition every 1/7th of a rotation.
|
||||||
|
|
||||||
|
If a track consists of two segments, one with clock rate 1 and one with clock rate 2, the second will be
|
||||||
|
clocked twice as fast as the first.
|
||||||
|
*/
|
||||||
|
struct PCMSegment {
|
||||||
|
Time duration;
|
||||||
|
std::unique_ptr<uint8_t> data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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(std::vector<PCMSegment> segments);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Creates a @c PCMTrack consisting of a single continuous run of data, implying a constant clock rate.
|
||||||
|
*/
|
||||||
|
PCMTrack(PCMSegment segment);
|
||||||
|
|
||||||
|
// as per @c Track
|
||||||
|
Event get_next_event();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// storage for the segments that describe this track
|
||||||
|
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;
|
||||||
|
|
||||||
|
// contains the master 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* PCMTrack_hpp */
|
Loading…
Reference in New Issue
Block a user