summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2022-04-19 14:03:20 +0200
committerCarl Hetherington <cth@carlh.net>2022-04-20 22:12:46 +0200
commit341ba1115b6285fec998901e50f9afb48bcaeeb6 (patch)
tree53d64b4e7a374c21c4839aa888f7d195ca865210
parentaba8cb303255a5d72ee17ca072d3ae31b7832af4 (diff)
Use std::vector in AudioBuffers (#2236).
-rw-r--r--src/lib/audio_analyser.cc4
-rw-r--r--src/lib/audio_analyser.h2
-rw-r--r--src/lib/audio_buffers.cc217
-rw-r--r--src/lib/audio_buffers.h52
-rw-r--r--src/lib/audio_filter_graph.cc2
-rw-r--r--src/lib/audio_filter_graph.h2
-rw-r--r--src/lib/audio_ring_buffers.cc2
-rw-r--r--src/lib/ffmpeg_file_encoder.cc2
-rw-r--r--src/lib/resampler.cc4
-rw-r--r--test/audio_buffers_test.cc43
10 files changed, 152 insertions, 178 deletions
diff --git a/src/lib/audio_analyser.cc b/src/lib/audio_analyser.cc
index 53d764a9b..755d6e9b0 100644
--- a/src/lib/audio_analyser.cc
+++ b/src/lib/audio_analyser.cc
@@ -134,7 +134,7 @@ AudioAnalyser::~AudioAnalyser ()
void
-AudioAnalyser::analyse (shared_ptr<const AudioBuffers> b, DCPTime time)
+AudioAnalyser::analyse (shared_ptr<AudioBuffers> b, DCPTime time)
{
LOG_DEBUG_AUDIO_ANALYSIS("Received %1 frames at %2", b->frames(), to_string(time));
DCPOMATIC_ASSERT (time >= _start);
@@ -150,7 +150,7 @@ AudioAnalyser::analyse (shared_ptr<const AudioBuffers> b, DCPTime time)
vector<double> interleaved(frames * channels);
for (int j = 0; j < channels; ++j) {
- float* data = b->data(j);
+ float const* data = b->data(j);
for (int i = 0; i < frames; ++i) {
float s = data[i];
diff --git a/src/lib/audio_analyser.h b/src/lib/audio_analyser.h
index 14c744285..01eec36b1 100644
--- a/src/lib/audio_analyser.h
+++ b/src/lib/audio_analyser.h
@@ -45,7 +45,7 @@ public:
AudioAnalyser (AudioAnalyser const&) = delete;
AudioAnalyser& operator= (AudioAnalyser const&) = delete;
- void analyse (std::shared_ptr<const AudioBuffers>, dcpomatic::DCPTime time);
+ void analyse (std::shared_ptr<AudioBuffers>, dcpomatic::DCPTime time);
dcpomatic::DCPTime start () const {
return _start;
diff --git a/src/lib/audio_buffers.cc b/src/lib/audio_buffers.cc
index 51f6c6c33..119a499b4 100644
--- a/src/lib/audio_buffers.cc
+++ b/src/lib/audio_buffers.cc
@@ -22,22 +22,18 @@
#include "audio_buffers.h"
#include "dcpomatic_assert.h"
#include "maths_util.h"
+#include "scope_guard.h"
#include <cassert>
#include <cstring>
#include <cmath>
-#include <stdexcept>
-using std::bad_alloc;
using std::shared_ptr;
using std::make_shared;
-/** Construct an AudioBuffers. Audio data is undefined after this constructor.
- * @param channels Number of channels.
- * @param frames Number of frames to reserve space for.
- */
-AudioBuffers::AudioBuffers (int channels, int32_t frames)
+/** Construct a silent AudioBuffers */
+AudioBuffers::AudioBuffers (int channels, int frames)
{
allocate (channels, frames);
}
@@ -48,21 +44,21 @@ AudioBuffers::AudioBuffers (int channels, int32_t frames)
*/
AudioBuffers::AudioBuffers (AudioBuffers const & other)
{
- allocate (other._channels, other._frames);
- copy_from (&other, other._frames, 0, 0);
+ allocate (other.channels(), other.frames());
+ copy_from (&other, other.frames(), 0, 0);
}
AudioBuffers::AudioBuffers (std::shared_ptr<const AudioBuffers> other)
{
- allocate (other->_channels, other->_frames);
- copy_from (other.get(), other->_frames, 0, 0);
+ allocate (other->channels(), other->frames());
+ copy_from (other.get(), other->frames(), 0, 0);
}
-AudioBuffers::AudioBuffers (std::shared_ptr<const AudioBuffers> other, int32_t frames_to_copy, int32_t read_offset)
+AudioBuffers::AudioBuffers (std::shared_ptr<const AudioBuffers> other, int frames_to_copy, int read_offset)
{
- allocate (other->_channels, frames_to_copy);
+ allocate (other->channels(), frames_to_copy);
copy_from (other.get(), frames_to_copy, read_offset, 0);
}
@@ -74,81 +70,55 @@ AudioBuffers::operator= (AudioBuffers const & other)
return *this;
}
- deallocate ();
- allocate (other._channels, other._frames);
- copy_from (&other, other._frames, 0, 0);
+ allocate (other.channels(), other.frames());
+ copy_from (&other, other.frames(), 0, 0);
return *this;
}
-/** AudioBuffers destructor */
-AudioBuffers::~AudioBuffers ()
-{
- deallocate ();
-}
-
-
void
-AudioBuffers::allocate (int channels, int32_t frames)
+AudioBuffers::allocate (int channels, int frames)
{
DCPOMATIC_ASSERT (frames >= 0);
- DCPOMATIC_ASSERT (channels >= 0);
+ DCPOMATIC_ASSERT (channels > 0);
- _channels = channels;
- _frames = frames;
- _allocated_frames = frames;
+ ScopeGuard sg = [this]() { update_data_pointers(); };
- _data = static_cast<float**> (malloc(_channels * sizeof(float *)));
- if (!_data) {
- throw bad_alloc ();
- }
-
- for (int i = 0; i < _channels; ++i) {
- _data[i] = static_cast<float*> (malloc(frames * sizeof(float)));
- if (!_data[i]) {
- throw bad_alloc ();
- }
+ _data.resize(channels);
+ for (int channel = 0; channel < channels; ++channel) {
+ _data[channel].resize(frames);
}
}
-void
-AudioBuffers::deallocate ()
+/** @param channel Channel index.
+ * @return Buffer for this channel.
+ */
+float*
+AudioBuffers::data (int channel)
{
- for (int i = 0; i < _channels; ++i) {
- free (_data[i]);
- }
-
- free (_data);
+ DCPOMATIC_ASSERT (channel >= 0 && channel < channels());
+ return _data[channel].data();
}
/** @param channel Channel index.
* @return Buffer for this channel.
*/
-float*
+float const*
AudioBuffers::data (int channel) const
{
- DCPOMATIC_ASSERT (channel >= 0 && channel < _channels);
- return _data[channel];
+ DCPOMATIC_ASSERT (channel >= 0 && channel < channels());
+ return _data[channel].data();
}
-/** Set the number of frames that these AudioBuffers will report themselves
- * as having. If we reduce the number of frames, the `lost' frames will
- * be silenced.
- * @param f Frames; must be less than or equal to the number of allocated frames.
- */
+/** Set the number of frames in these AudioBuffers */
void
-AudioBuffers::set_frames (int32_t frames)
+AudioBuffers::set_frames (int frames)
{
- DCPOMATIC_ASSERT (frames <= _allocated_frames);
-
- if (frames < _frames) {
- make_silent (frames, _frames - frames);
- }
- _frames = frames;
+ allocate(_data.size(), frames);
}
@@ -156,7 +126,7 @@ AudioBuffers::set_frames (int32_t frames)
void
AudioBuffers::make_silent ()
{
- for (int channel = 0; channel < _channels; ++channel) {
+ for (int channel = 0; channel < channels(); ++channel) {
make_silent (channel);
}
}
@@ -166,29 +136,28 @@ AudioBuffers::make_silent ()
void
AudioBuffers::make_silent (int channel)
{
- DCPOMATIC_ASSERT (channel >= 0 && channel < _channels);
+ DCPOMATIC_ASSERT (channel >= 0 && channel < channels());
/* This isn't really allowed, as all-bits-0 is not guaranteed to mean a 0 float,
but it seems that we can get away with it.
*/
- memset (_data[channel], 0, _frames * sizeof(float));
+ memset (data(channel), 0, frames() * sizeof(float));
}
-/** Make some frames.
+/** Make some frames silent.
* @param from Start frame.
- * @param frames Number of frames to silence.
*/
void
-AudioBuffers::make_silent (int32_t from, int32_t frames)
+AudioBuffers::make_silent (int from, int frames_to_silence)
{
- DCPOMATIC_ASSERT ((from + frames) <= _allocated_frames);
+ DCPOMATIC_ASSERT ((from + frames_to_silence) <= frames());
- for (int channel = 0; channel < _channels; ++channel) {
+ for (int channel = 0; channel < channels(); ++channel) {
/* This isn't really allowed, as all-bits-0 is not guaranteed to mean a 0 float,
but it seems that we can get away with it.
*/
- memset (_data[channel] + from, 0, frames * sizeof(float));
+ memset (data(channel) + from, 0, frames_to_silence * sizeof(float));
}
}
@@ -200,7 +169,7 @@ AudioBuffers::make_silent (int32_t from, int32_t frames)
* @param write_offset Offset to write to in `to'.
*/
void
-AudioBuffers::copy_from (AudioBuffers const * from, int32_t frames_to_copy, int32_t read_offset, int32_t write_offset)
+AudioBuffers::copy_from (AudioBuffers const * from, int frames_to_copy, int read_offset, int write_offset)
{
if (frames_to_copy == 0) {
/* Prevent the asserts from firing if there is nothing to do */
@@ -209,38 +178,38 @@ AudioBuffers::copy_from (AudioBuffers const * from, int32_t frames_to_copy, int3
DCPOMATIC_ASSERT (from);
DCPOMATIC_ASSERT (from->channels() == channels());
- DCPOMATIC_ASSERT (read_offset >= 0 && (read_offset + frames_to_copy) <= from->_allocated_frames);
- DCPOMATIC_ASSERT (write_offset >= 0 && (write_offset + frames_to_copy) <= _allocated_frames);
+ DCPOMATIC_ASSERT (read_offset >= 0 && (read_offset + frames_to_copy) <= from->frames());
+ DCPOMATIC_ASSERT (write_offset >= 0 && (write_offset + frames_to_copy) <= frames());
- for (int i = 0; i < _channels; ++i) {
- memcpy (_data[i] + write_offset, from->_data[i] + read_offset, frames_to_copy * sizeof(float));
+ for (int channel = 0; channel < channels(); ++channel) {
+ memcpy (data(channel) + write_offset, from->data(channel) + read_offset, frames_to_copy * sizeof(float));
}
}
/** Move audio data around.
+ * @param frames_to_move Number of frames to move.
* @param from Offset to move from.
* @param to Offset to move to.
- * @param frames Number of frames to move.
*/
void
-AudioBuffers::move (int32_t frames, int32_t from, int32_t to)
+AudioBuffers::move (int frames_to_move, int from, int to)
{
- if (frames == 0) {
+ if (frames_to_move == 0) {
return;
}
DCPOMATIC_ASSERT (from >= 0);
- DCPOMATIC_ASSERT (from < _frames);
+ DCPOMATIC_ASSERT (from < frames());
DCPOMATIC_ASSERT (to >= 0);
- DCPOMATIC_ASSERT (to < _frames);
- DCPOMATIC_ASSERT (frames > 0);
- DCPOMATIC_ASSERT (frames <= _frames);
- DCPOMATIC_ASSERT ((from + frames) <= _frames);
- DCPOMATIC_ASSERT ((to + frames) <= _allocated_frames);
-
- for (int i = 0; i < _channels; ++i) {
- memmove (_data[i] + to, _data[i] + from, frames * sizeof(float));
+ DCPOMATIC_ASSERT (to < frames());
+ DCPOMATIC_ASSERT (frames_to_move > 0);
+ DCPOMATIC_ASSERT (frames_to_move <= frames());
+ DCPOMATIC_ASSERT ((from + frames_to_move) <= frames());
+ DCPOMATIC_ASSERT ((to + frames_to_move) <= frames());
+
+ for (int channel = 0; channel < channels(); ++channel) {
+ memmove (data(channel) + to, data(channel) + from, frames_to_move * sizeof(float));
}
}
@@ -256,10 +225,10 @@ AudioBuffers::accumulate_channel (AudioBuffers const * from, int from_channel, i
{
int const N = frames ();
DCPOMATIC_ASSERT (from->frames() == N);
- DCPOMATIC_ASSERT (to_channel <= _channels);
+ DCPOMATIC_ASSERT (to_channel <= channels());
auto s = from->data (from_channel);
- auto d = _data[to_channel];
+ auto d = data(to_channel);
for (int i = 0; i < N; ++i) {
*d++ += (*s++) * gain;
@@ -267,42 +236,6 @@ AudioBuffers::accumulate_channel (AudioBuffers const * from, int from_channel, i
}
-/** Ensure we have space for at least a certain number of frames. If we extend
- * the buffers, fill the new space with silence.
- */
-void
-AudioBuffers::ensure_size (int32_t frames)
-{
- if (_allocated_frames >= frames) {
- return;
- }
-
- /* Round up frames to the next power of 2 to reduce the number
- of realloc()s that are necessary.
- */
- frames--;
- frames |= frames >> 1;
- frames |= frames >> 2;
- frames |= frames >> 4;
- frames |= frames >> 8;
- frames |= frames >> 16;
- frames++;
-
- for (int i = 0; i < _channels; ++i) {
- _data[i] = static_cast<float*> (realloc(_data[i], frames * sizeof(float)));
- if (!_data[i]) {
- throw bad_alloc ();
- }
- }
-
- auto const old_allocated = _allocated_frames;
- _allocated_frames = frames;
- if (old_allocated < _allocated_frames) {
- make_silent (old_allocated, _allocated_frames - old_allocated);
- }
-}
-
-
/** Mix some other buffers with these ones. The AudioBuffers must have the same number of channels.
* @param from Audio buffers to get data from.
* @param frames Number of frames to mix.
@@ -310,14 +243,14 @@ AudioBuffers::ensure_size (int32_t frames)
* @param write_offset Offset within this to mix into.
*/
void
-AudioBuffers::accumulate_frames (AudioBuffers const * from, int32_t frames, int32_t read_offset, int32_t write_offset)
+AudioBuffers::accumulate_frames (AudioBuffers const * from, int frames, int read_offset, int write_offset)
{
- DCPOMATIC_ASSERT (_channels == from->channels ());
+ DCPOMATIC_ASSERT (channels() == from->channels());
DCPOMATIC_ASSERT (read_offset >= 0);
DCPOMATIC_ASSERT (write_offset >= 0);
auto from_data = from->data ();
- for (int i = 0; i < _channels; ++i) {
+ for (int i = 0; i < channels(); ++i) {
for (int j = 0; j < frames; ++j) {
_data[i][j + write_offset] += from_data[i][j + read_offset];
}
@@ -331,14 +264,15 @@ AudioBuffers::apply_gain (float dB)
{
auto const linear = db_to_linear (dB);
- for (int i = 0; i < _channels; ++i) {
- for (int j = 0; j < _frames; ++j) {
+ for (int i = 0; i < channels(); ++i) {
+ for (int j = 0; j < frames(); ++j) {
_data[i][j] *= linear;
}
}
}
+/** @return AudioBuffers object containing only the given channel from this AudioBuffers */
shared_ptr<AudioBuffers>
AudioBuffers::channel (int channel) const
{
@@ -376,17 +310,28 @@ void
AudioBuffers::append (shared_ptr<const AudioBuffers> other)
{
DCPOMATIC_ASSERT (channels() == other->channels());
- ensure_size (_frames + other->frames());
- copy_from (other.get(), other->frames(), 0, _frames);
- _frames += other->frames();
+ auto old_frames = frames();
+ set_frames(old_frames + other->frames());
+ copy_from (other.get(), other->frames(), 0, old_frames);
}
/** Remove some frames from the start of these AudioBuffers */
void
-AudioBuffers::trim_start (int32_t frames)
+AudioBuffers::trim_start (int frames_to_trim)
{
- DCPOMATIC_ASSERT (frames <= _frames);
- move (_frames - frames, frames, 0);
- set_frames (_frames - frames);
+ DCPOMATIC_ASSERT (frames_to_trim <= frames());
+ move (frames() - frames_to_trim, frames_to_trim, 0);
+ set_frames (frames() - frames_to_trim);
}
+
+
+void
+AudioBuffers::update_data_pointers ()
+{
+ _data_pointers.resize (channels());
+ for (int i = 0; i < channels(); ++i) {
+ _data_pointers[i] = _data[i].data();
+ }
+}
+
diff --git a/src/lib/audio_buffers.h b/src/lib/audio_buffers.h
index 1f0f5f28a..4db0fa255 100644
--- a/src/lib/audio_buffers.h
+++ b/src/lib/audio_buffers.h
@@ -28,75 +28,65 @@
#define DCPOMATIC_AUDIO_BUFFERS_H
-#include <stdint.h>
#include <memory>
+#include <vector>
/** @class AudioBuffers
* @brief A class to hold multi-channel audio data in float format.
- *
- * The use of int32_t for frame counts in this class is due to the
- * round-up to the next power-of-2 code in ensure_size(); if that
- * were changed the frame count could use any integer type.
*/
class AudioBuffers
{
public:
- AudioBuffers (int channels, int32_t frames);
+ AudioBuffers (int channels, int frames);
AudioBuffers (AudioBuffers const &);
explicit AudioBuffers (std::shared_ptr<const AudioBuffers>);
- AudioBuffers (std::shared_ptr<const AudioBuffers> other, int32_t frames_to_copy, int32_t read_offset);
- ~AudioBuffers ();
+ AudioBuffers (std::shared_ptr<const AudioBuffers> other, int frames_to_copy, int read_offset);
AudioBuffers & operator= (AudioBuffers const &);
std::shared_ptr<AudioBuffers> clone () const;
std::shared_ptr<AudioBuffers> channel (int) const;
- void ensure_size (int32_t);
-
- float** data () const {
- return _data;
+ float* const* data () const {
+ return _data_pointers.data();
}
- float* data (int) const;
+ float const* data (int) const;
+ float* data (int);
int channels () const {
- return _channels;
+ return _data.size();
}
int frames () const {
- return _frames;
+ return _data[0].size();
}
- void set_frames (int32_t f);
+ void set_frames (int f);
void make_silent ();
void make_silent (int channel);
- void make_silent (int32_t from, int32_t frames);
+ void make_silent (int from, int frames);
void apply_gain (float);
- void copy_from (AudioBuffers const * from, int32_t frames_to_copy, int32_t read_offset, int32_t write_offset);
+ void copy_from (AudioBuffers const * from, int frames_to_copy, int read_offset, int write_offset);
void copy_channel_from (AudioBuffers const * from, int from_channel, int to_channel);
- void move (int32_t frames, int32_t from, int32_t to);
+ void move (int frames, int from, int to);
void accumulate_channel (AudioBuffers const * from, int from_channel, int to_channel, float gain = 1);
- void accumulate_frames (AudioBuffers const * from, int32_t frames, int32_t read_offset, int32_t write_offset);
+ void accumulate_frames (AudioBuffers const * from, int frames, int read_offset, int write_offset);
void append (std::shared_ptr<const AudioBuffers> other);
- void trim_start (int32_t frames);
+ void trim_start (int frames);
private:
- void allocate (int channels, int32_t frames);
- void deallocate ();
-
- /** Number of channels */
- int _channels;
- /** Number of frames (where a frame is one sample across all channels) */
- int32_t _frames;
- /** Number of frames that _data can hold */
- int32_t _allocated_frames;
+ void allocate (int channels, int frames);
+ void update_data_pointers ();
+
/** Audio data (so that, e.g. _data[2][6] is channel 2, sample 6) */
- float** _data;
+ std::vector<std::vector<float>> _data;
+ /** Pointers to the data of each vector in _data */
+ std::vector<float*> _data_pointers;
};
diff --git a/src/lib/audio_filter_graph.cc b/src/lib/audio_filter_graph.cc
index 95f6730cf..d9e4e244f 100644
--- a/src/lib/audio_filter_graph.cc
+++ b/src/lib/audio_filter_graph.cc
@@ -106,7 +106,7 @@ AudioFilterGraph::sink_name () const
}
void
-AudioFilterGraph::process (shared_ptr<const AudioBuffers> buffers)
+AudioFilterGraph::process (shared_ptr<AudioBuffers> buffers)
{
DCPOMATIC_ASSERT (buffers->frames() > 0);
int const process_channels = av_get_channel_layout_nb_channels (_channel_layout);
diff --git a/src/lib/audio_filter_graph.h b/src/lib/audio_filter_graph.h
index af438a7e7..e749d0ec9 100644
--- a/src/lib/audio_filter_graph.h
+++ b/src/lib/audio_filter_graph.h
@@ -31,7 +31,7 @@ public:
AudioFilterGraph (int sample_rate, int channels);
~AudioFilterGraph ();
- void process (std::shared_ptr<const AudioBuffers> audio);
+ void process (std::shared_ptr<AudioBuffers> audio);
protected:
std::string src_parameters () const override;
diff --git a/src/lib/audio_ring_buffers.cc b/src/lib/audio_ring_buffers.cc
index 1a216ab33..b55631a1c 100644
--- a/src/lib/audio_ring_buffers.cc
+++ b/src/lib/audio_ring_buffers.cc
@@ -85,7 +85,7 @@ AudioRingBuffers::get (float* out, int channels, int frames)
}
int const to_do = min (frames, front.first->frames() - _used_in_head);
- float** p = front.first->data();
+ float* const* p = front.first->data();
int const c = min (front.first->channels(), channels);
for (int i = 0; i < to_do; ++i) {
for (int j = 0; j < c; ++j) {
diff --git a/src/lib/ffmpeg_file_encoder.cc b/src/lib/ffmpeg_file_encoder.cc
index 57103abc7..62242d65c 100644
--- a/src/lib/ffmpeg_file_encoder.cc
+++ b/src/lib/ffmpeg_file_encoder.cc
@@ -127,7 +127,7 @@ public:
return false;
}
- void write (int size, int channel_offset, int channels, float** data, int64_t sample_offset)
+ void write (int size, int channel_offset, int channels, float* const* data, int64_t sample_offset)
{
DCPOMATIC_ASSERT (size);
diff --git a/src/lib/resampler.cc b/src/lib/resampler.cc
index 056b2e1ee..4447ccf0d 100644
--- a/src/lib/resampler.cc
+++ b/src/lib/resampler.cc
@@ -131,7 +131,6 @@ Resampler::run (shared_ptr<const AudioBuffers> in)
break;
}
- resampled->ensure_size (out_offset + data.output_frames_gen);
resampled->set_frames (out_offset + data.output_frames_gen);
{
@@ -176,7 +175,7 @@ Resampler::flush ()
throw EncodeError (String::compose(N_("could not run sample-rate converter (%1)"), src_strerror(r)));
}
- out->ensure_size (out_offset + data.output_frames_gen);
+ out->set_frames (out_offset + data.output_frames_gen);
auto p = data.data_out;
auto q = out->data ();
@@ -187,7 +186,6 @@ Resampler::flush ()
}
out_offset += data.output_frames_gen;
- out->set_frames (out_offset);
return out;
}
diff --git a/test/audio_buffers_test.cc b/test/audio_buffers_test.cc
index 921592f55..0abd73080 100644
--- a/test/audio_buffers_test.cc
+++ b/test/audio_buffers_test.cc
@@ -79,7 +79,7 @@ BOOST_AUTO_TEST_CASE (audio_buffers_extend_test)
random_fill (buffers);
/* Extend */
- buffers.ensure_size (299);
+ buffers.set_frames (299);
srand (1);
random_check (buffers, 0, 150);
@@ -303,3 +303,44 @@ BOOST_AUTO_TEST_CASE (audio_buffers_accumulate_frames)
}
}
}
+
+
+BOOST_AUTO_TEST_CASE (audio_buffers_data)
+{
+ AudioBuffers a (94, 512);
+
+ for (int i = 0; i < 94; ++i) {
+ BOOST_CHECK_EQUAL (a.data()[i], a.data(i));
+ }
+
+ a.set_frames (2048);
+
+ for (int i = 0; i < 94; ++i) {
+ BOOST_CHECK_EQUAL (a.data()[i], a.data(i));
+ }
+}
+
+
+BOOST_AUTO_TEST_CASE (audio_buffers_trim_start)
+{
+ AudioBuffers a (13, 999);
+
+ srand (55);
+ random_fill (a);
+
+ a.trim_start (101);
+
+ srand (55);
+
+ /* Burn the first 101 numbers in the sequence */
+ for (int i = 0; i < 101 * 13; ++i) {
+ random_float ();
+ }
+
+ for (int i = 0; i < (999 - 101); ++i) {
+ for (int j = 0; j < 13; ++j) {
+ BOOST_CHECK_CLOSE (a.data(j)[i], random_float(), tolerance);
+ }
+ }
+}
+