return make_pair(min_value_, max_value_);
}
-SegmentAnalogDataIterator* AnalogSegment::begin_sample_iteration(uint64_t start)
+float* AnalogSegment::get_iterator_value_ptr(SegmentDataIterator* it)
{
- return (SegmentAnalogDataIterator*)begin_raw_sample_iteration(start);
-}
+ assert(it->sample_index <= (sample_count_ - 1));
-void AnalogSegment::continue_sample_iteration(SegmentAnalogDataIterator* it, uint64_t increase)
-{
- Segment::continue_raw_sample_iteration((SegmentRawDataIterator*)it, increase);
-}
-
-void AnalogSegment::end_sample_iteration(SegmentAnalogDataIterator* it)
-{
- Segment::end_raw_sample_iteration((SegmentRawDataIterator*)it);
+ return (float*)(it->chunk + it->chunk_offs);
}
void AnalogSegment::get_envelope_section(EnvelopeSection &s,
Envelope &e0 = envelope_levels_[0];
uint64_t prev_length;
EnvelopeSample *dest_ptr;
- SegmentRawDataIterator* it;
+ SegmentDataIterator* it;
// Expand the data buffer to fit the new samples
prev_length = e0.length;
// Calculate min/max values in case we have too few samples for an envelope
const float old_min_value = min_value_, old_max_value = max_value_;
if (sample_count_ < EnvelopeScaleFactor) {
- it = begin_raw_sample_iteration(0);
+ it = begin_sample_iteration(0);
for (uint64_t i = 0; i < sample_count_; i++) {
- const float sample = *((float*)it->value);
+ const float sample = *get_iterator_value_ptr(it);
if (sample < min_value_)
min_value_ = sample;
if (sample > max_value_)
max_value_ = sample;
- continue_raw_sample_iteration(it, 1);
+ continue_sample_iteration(it, 1);
}
- end_raw_sample_iteration(it);
+ end_sample_iteration(it);
}
// Break off if there are no new samples to compute
uint64_t start_sample = prev_length * EnvelopeScaleFactor;
uint64_t end_sample = e0.length * EnvelopeScaleFactor;
- it = begin_raw_sample_iteration(start_sample);
+ it = begin_sample_iteration(start_sample);
for (uint64_t i = start_sample; i < end_sample; i += EnvelopeScaleFactor) {
- const float* samples = (float*)it->value;
+ const float* samples = get_iterator_value_ptr(it);
const EnvelopeSample sub_sample = {
*min_element(samples, samples + EnvelopeScaleFactor),
if (sub_sample.max > max_value_)
max_value_ = sub_sample.max;
- continue_raw_sample_iteration(it, EnvelopeScaleFactor);
+ continue_sample_iteration(it, EnvelopeScaleFactor);
*dest_ptr++ = sub_sample;
}
- end_raw_sample_iteration(it);
+ end_sample_iteration(it);
// Compute higher level mipmaps
for (unsigned int level = 1; level < ScaleStepCount; level++) {
class Analog;
-typedef struct {
- uint64_t sample_index, chunk_num, chunk_offs;
- uint8_t* chunk;
- float* value;
-} SegmentAnalogDataIterator;
-
class AnalogSegment : public Segment
{
Q_OBJECT
const pair<float, float> get_min_max() const;
- SegmentAnalogDataIterator* begin_sample_iteration(uint64_t start);
- void continue_sample_iteration(SegmentAnalogDataIterator* it, uint64_t increase);
- void end_sample_iteration(SegmentAnalogDataIterator* it);
+ float* get_iterator_value_ptr(SegmentDataIterator* it);
void get_envelope_section(EnvelopeSection &s,
uint64_t start, uint64_t end, float min_length) const;
get_raw_samples(start_sample, (end_sample - start_sample), dest);
}
-SegmentLogicDataIterator* LogicSegment::begin_sample_iteration(uint64_t start)
-{
- return (SegmentLogicDataIterator*)begin_raw_sample_iteration(start);
-}
-
-void LogicSegment::continue_sample_iteration(SegmentLogicDataIterator* it, uint64_t increase)
-{
- Segment::continue_raw_sample_iteration((SegmentRawDataIterator*)it, increase);
-}
-
-void LogicSegment::end_sample_iteration(SegmentLogicDataIterator* it)
-{
- Segment::end_raw_sample_iteration((SegmentRawDataIterator*)it);
-}
-
void LogicSegment::get_subsampled_edges(
vector<EdgePair> &edges,
uint64_t start, uint64_t end,
MipMapLevel &m0 = mip_map_[0];
uint64_t prev_length;
uint8_t *dest_ptr;
- SegmentRawDataIterator* it;
+ SegmentDataIterator* it;
uint64_t accumulator;
unsigned int diff_counter;
const uint64_t start_sample = prev_length * MipMapScaleFactor;
const uint64_t end_sample = m0.length * MipMapScaleFactor;
- it = begin_raw_sample_iteration(start_sample);
+ it = begin_sample_iteration(start_sample);
for (uint64_t i = start_sample; i < end_sample;) {
// Accumulate transitions which have occurred in this sample
accumulator = 0;
diff_counter = MipMapScaleFactor;
while (diff_counter-- > 0) {
- const uint64_t sample = unpack_sample(it->value);
+ const uint64_t sample = unpack_sample(get_iterator_value(it));
accumulator |= last_append_sample_ ^ sample;
last_append_sample_ = sample;
- continue_raw_sample_iteration(it, 1);
+ continue_sample_iteration(it, 1);
i++;
}
pack_sample(dest_ptr, accumulator);
dest_ptr += unit_size_;
}
- end_raw_sample_iteration(it);
+ end_sample_iteration(it);
// Compute higher level mipmaps
for (unsigned int level = 1; level < ScaleStepCount; level++) {
class Logic;
-typedef struct {
- uint64_t sample_index, chunk_num, chunk_offs;
- uint8_t* chunk;
- uint8_t* value;
-} SegmentLogicDataIterator;
-
class LogicSegment : public Segment
{
Q_OBJECT
void get_samples(int64_t start_sample, int64_t end_sample, uint8_t* dest) const;
- SegmentLogicDataIterator* begin_sample_iteration(uint64_t start);
- void continue_sample_iteration(SegmentLogicDataIterator* it, uint64_t increase);
- void end_sample_iteration(SegmentLogicDataIterator* it);
-
/**
* Parses a logic data segment to generate a list of transitions
* in a time interval to a given level of detail.
#include <cstdlib>
#include <cstring>
+#include <QDebug>
+
using std::bad_alloc;
using std::lock_guard;
using std::min;
}
}
-SegmentRawDataIterator* Segment::begin_raw_sample_iteration(uint64_t start)
+SegmentDataIterator* Segment::begin_sample_iteration(uint64_t start)
{
- SegmentRawDataIterator* it = new SegmentRawDataIterator;
+ SegmentDataIterator* it = new SegmentDataIterator;
assert(start < sample_count_);
it->chunk_num = (start * unit_size_) / chunk_size_;
it->chunk_offs = (start * unit_size_) % chunk_size_;
it->chunk = data_chunks_[it->chunk_num];
- it->value = it->chunk + it->chunk_offs;
return it;
}
-void Segment::continue_raw_sample_iteration(SegmentRawDataIterator* it, uint64_t increase)
+void Segment::continue_sample_iteration(SegmentDataIterator* it, uint64_t increase)
{
- // Fail gracefully if we are asked to deliver data we don't have
- if (it->sample_index > sample_count_)
- return;
-
it->sample_index += increase;
it->chunk_offs += (increase * unit_size_);
it->chunk_offs -= chunk_size_;
it->chunk = data_chunks_[it->chunk_num];
}
-
- it->value = it->chunk + it->chunk_offs;
}
-void Segment::end_raw_sample_iteration(SegmentRawDataIterator* it)
+void Segment::end_sample_iteration(SegmentDataIterator* it)
{
delete it;
}
}
+uint8_t* Segment::get_iterator_value(SegmentDataIterator* it)
+{
+ assert(it->sample_index <= (sample_count_ - 1));
+
+ return (it->chunk + it->chunk_offs);
+}
+
} // namespace data
} // namespace pv
typedef struct {
uint64_t sample_index, chunk_num, chunk_offs;
uint8_t* chunk;
- uint8_t* value;
-} SegmentRawDataIterator;
+} SegmentDataIterator;
class Segment : public QObject
{
void append_samples(void *data, uint64_t samples);
void get_raw_samples(uint64_t start, uint64_t count, uint8_t *dest) const;
- SegmentRawDataIterator* begin_raw_sample_iteration(uint64_t start);
- void continue_raw_sample_iteration(SegmentRawDataIterator* it, uint64_t increase);
- void end_raw_sample_iteration(SegmentRawDataIterator* it);
+ SegmentDataIterator* begin_sample_iteration(uint64_t start);
+ void continue_sample_iteration(SegmentDataIterator* it, uint64_t increase);
+ void end_sample_iteration(SegmentDataIterator* it);
+ uint8_t* get_iterator_value(SegmentDataIterator* it);
uint32_t segment_id_;
mutable recursive_mutex mutex_;
BOOST_CHECK(s.get_sample_count() == num_samples);
- pv::data::SegmentRawDataIterator* it = s.begin_raw_sample_iteration(0);
+ pv::data::SegmentDataIterator* it = s.begin_sample_iteration(0);
for (uint32_t i = 0; i < num_samples; i++) {
- uint8_t* sample_data = it->value;
- BOOST_CHECK_EQUAL(*((uint32_t*)sample_data), i);
- s.continue_raw_sample_iteration(it, 1);
+ BOOST_CHECK_EQUAL(*((uint32_t*)s.get_iterator_value(it)), i);
+ s.continue_sample_iteration(it, 1);
}
- s.end_raw_sample_iteration(it);
+ s.end_sample_iteration(it);
}
BOOST_AUTO_TEST_SUITE_END()