2016-12-18 02:13:57 +00:00
|
|
|
//
|
|
|
|
// PCMSegment.hpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 17/12/2016.
|
|
|
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef PCMSegment_hpp
|
|
|
|
#define PCMSegment_hpp
|
|
|
|
|
|
|
|
#include <cstdint>
|
2017-11-10 03:04:49 +00:00
|
|
|
#include <memory>
|
2016-12-18 02:13:57 +00:00
|
|
|
#include <vector>
|
|
|
|
|
2017-09-23 02:39:23 +00:00
|
|
|
#include "../../Storage.hpp"
|
|
|
|
#include "Track.hpp"
|
2016-12-18 02:13:57 +00:00
|
|
|
|
|
|
|
namespace Storage {
|
|
|
|
namespace Disk {
|
|
|
|
|
|
|
|
/*!
|
|
|
|
A segment of PCM-sampled data.
|
|
|
|
|
|
|
|
Bits from each byte are taken MSB to LSB.
|
|
|
|
*/
|
|
|
|
struct PCMSegment {
|
|
|
|
Time length_of_a_bit;
|
2018-01-10 03:12:34 +00:00
|
|
|
unsigned int number_of_bits = 0;
|
2016-12-18 02:13:57 +00:00
|
|
|
std::vector<uint8_t> data;
|
2016-12-22 03:17:00 +00:00
|
|
|
|
|
|
|
PCMSegment(Time length_of_a_bit, unsigned int number_of_bits, std::vector<uint8_t> data)
|
|
|
|
: length_of_a_bit(length_of_a_bit), number_of_bits(number_of_bits), data(data) {}
|
|
|
|
PCMSegment() {}
|
2017-09-25 02:41:16 +00:00
|
|
|
|
2017-11-11 20:28:40 +00:00
|
|
|
int bit(std::size_t index) const {
|
2017-09-25 02:41:16 +00:00
|
|
|
return (data[index >> 3] >> (7 ^ (index & 7)))&1;
|
|
|
|
}
|
2018-01-10 03:12:34 +00:00
|
|
|
|
|
|
|
void clear() {
|
|
|
|
number_of_bits = 0;
|
|
|
|
data.clear();
|
|
|
|
}
|
2016-12-18 02:13:57 +00:00
|
|
|
};
|
|
|
|
|
2016-12-19 03:53:24 +00:00
|
|
|
/*!
|
|
|
|
Provides a stream of events by inspecting a PCMSegment.
|
|
|
|
*/
|
2016-12-18 02:13:57 +00:00
|
|
|
class PCMSegmentEventSource {
|
|
|
|
public:
|
2016-12-19 03:53:24 +00:00
|
|
|
/*!
|
|
|
|
Constructs a @c PCMSegmentEventSource that will derive events from @c segment.
|
|
|
|
The event source is initially @c reset.
|
|
|
|
*/
|
2016-12-30 19:23:26 +00:00
|
|
|
PCMSegmentEventSource(const PCMSegment &);
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Copy constructor; produces a segment event source with the same underlying segment
|
|
|
|
but a unique pointer into it.
|
|
|
|
*/
|
|
|
|
PCMSegmentEventSource(const PCMSegmentEventSource &);
|
2016-12-18 02:13:57 +00:00
|
|
|
|
2016-12-19 03:53:24 +00:00
|
|
|
/*!
|
|
|
|
@returns the next event that will occur in this event stream.
|
|
|
|
*/
|
2016-12-18 02:13:57 +00:00
|
|
|
Track::Event get_next_event();
|
2016-12-19 03:53:24 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Resets the event source to the beginning of its event stream, exactly as if
|
|
|
|
it has just been constructed.
|
|
|
|
*/
|
2016-12-18 02:13:57 +00:00
|
|
|
void reset();
|
|
|
|
|
2016-12-19 03:53:24 +00:00
|
|
|
/*!
|
|
|
|
Seeks as close to @c time_from_start as the event source can manage while not
|
|
|
|
exceeding it.
|
|
|
|
|
|
|
|
@returns the time the source is now at.
|
|
|
|
*/
|
2016-12-18 03:44:33 +00:00
|
|
|
Time seek_to(const Time &time_from_start);
|
2016-12-19 03:53:24 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
@returns the total length of the stream of data that the source will provide.
|
|
|
|
*/
|
2016-12-18 03:44:33 +00:00
|
|
|
Time get_length();
|
|
|
|
|
2016-12-18 02:13:57 +00:00
|
|
|
private:
|
2016-12-30 19:23:26 +00:00
|
|
|
std::shared_ptr<PCMSegment> segment_;
|
2017-11-11 20:28:40 +00:00
|
|
|
std::size_t bit_pointer_;
|
2016-12-18 02:13:57 +00:00
|
|
|
Track::Event next_event_;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* PCMSegment_hpp */
|