summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gr-blocks/lib/wavfile_sink_impl.cc28
-rw-r--r--gr-blocks/lib/wavfile_sink_impl.h4
-rw-r--r--gr-blocks/lib/wavfile_source_impl.cc37
-rw-r--r--gr-blocks/lib/wavfile_source_impl.h4
4 files changed, 46 insertions, 27 deletions
diff --git a/gr-blocks/lib/wavfile_sink_impl.cc b/gr-blocks/lib/wavfile_sink_impl.cc
index 38325856bb..5e3362d92d 100644
--- a/gr-blocks/lib/wavfile_sink_impl.cc
+++ b/gr-blocks/lib/wavfile_sink_impl.cc
@@ -49,8 +49,9 @@ wavfile_sink_impl::wavfile_sink_impl(const char* filename,
{
int bits_per_sample;
- if (n_channels > 24) {
- throw std::runtime_error("Number of channels greater than 24 not supported.");
+ if (n_channels > s_max_channels) {
+ throw std::runtime_error("Number of channels greater than " +
+ std::to_string(s_max_channels) + " not supported.");
}
d_h.sample_rate = sample_rate;
@@ -86,6 +87,9 @@ wavfile_sink_impl::wavfile_sink_impl(const char* filename,
set_bits_per_sample_unlocked(bits_per_sample);
d_h.bytes_per_sample = d_bytes_per_sample_new;
+ set_max_noutput_items(s_items_size);
+ d_buffer.resize(s_items_size * d_h.nchans);
+
if (!open(filename)) {
throw std::runtime_error("Can't open WAV file.");
}
@@ -243,7 +247,6 @@ int wavfile_sink_impl::work(int noutput_items,
int n_in_chans = input_items.size();
int nwritten;
int errnum;
- float sample[24];
gr::thread::scoped_lock guard(d_mutex); // hold mutex for duration of this block
do_update(); // update: d_fp is read
@@ -257,21 +260,20 @@ int wavfile_sink_impl::work(int noutput_items,
// Write zeros to channels which are in the WAV file
// but don't have any inputs here
if (chan < n_in_chans) {
- sample[chan] = in[chan][nwritten];
+ d_buffer[chan + (nwritten * nchans)] = in[chan][nwritten];
} else {
- sample[chan] = 0;
+ d_buffer[chan + (nwritten * nchans)] = 0;
}
}
+ }
- sf_write_float(d_fp, &sample[0], nchans);
+ sf_write_float(d_fp, &d_buffer[0], nchans * nwritten);
- errnum = sf_error(d_fp);
- if (errnum) {
- GR_LOG_ERROR(d_logger,
- boost::format("sf_error: %s") % sf_error_number(errnum));
- close();
- throw std::runtime_error("File I/O error.");
- }
+ errnum = sf_error(d_fp);
+ if (errnum) {
+ GR_LOG_ERROR(d_logger, boost::format("sf_error: %s") % sf_error_number(errnum));
+ close();
+ throw std::runtime_error("File I/O error.");
}
return nwritten;
diff --git a/gr-blocks/lib/wavfile_sink_impl.h b/gr-blocks/lib/wavfile_sink_impl.h
index c837592ad9..48cf81b7f0 100644
--- a/gr-blocks/lib/wavfile_sink_impl.h
+++ b/gr-blocks/lib/wavfile_sink_impl.h
@@ -29,12 +29,16 @@ private:
float d_min_sample_val;
float d_normalize_shift;
float d_normalize_fac;
+ std::vector<float> d_buffer;
SNDFILE* d_fp;
SNDFILE* d_new_fp;
bool d_updated;
boost::mutex d_mutex;
+ static constexpr int s_items_size = 8192;
+ static constexpr int s_max_channels = 24;
+
/*!
* \brief If any file changes have occurred, update now. This is called
* internally by work() and thus doesn't usually need to be called by
diff --git a/gr-blocks/lib/wavfile_source_impl.cc b/gr-blocks/lib/wavfile_source_impl.cc
index 06db72c7e5..d013e20be9 100644
--- a/gr-blocks/lib/wavfile_source_impl.cc
+++ b/gr-blocks/lib/wavfile_source_impl.cc
@@ -46,8 +46,9 @@ wavfile_source_impl::wavfile_source_impl(const char* filename, bool repeat)
d_h.sample_rate = (unsigned)sfinfo.samplerate;
d_h.nchans = sfinfo.channels;
- if (sfinfo.channels > 24) {
- throw std::runtime_error("Number of channels greater than 24 not supported.");
+ if (sfinfo.channels > s_max_channels) {
+ throw std::runtime_error("Number of channels greater than " +
+ std::to_string(s_max_channels) + " not supported.");
}
switch (sfinfo.format & SF_FORMAT_SUBMASK) {
@@ -79,6 +80,9 @@ wavfile_source_impl::wavfile_source_impl(const char* filename, bool repeat)
throw std::runtime_error("WAV file does not contain any samples.");
}
+ set_output_multiple(s_items_size);
+ d_buffer.resize(s_items_size * d_h.nchans);
+
// Re-set the output signature
set_output_signature(io_signature::make(1, d_h.nchans, sizeof(float)));
}
@@ -91,15 +95,16 @@ int wavfile_source_impl::work(int noutput_items,
{
auto out = (float**)&output_items[0];
int n_out_chans = output_items.size();
- int i;
+ int items = 0;
+ int produced = 0;
int errnum;
- float sample[24];
+ sf_count_t samples;
- for (i = 0; i < noutput_items; i++) {
+ for (int i = 0; i < noutput_items; i += s_items_size) {
if (d_sample_idx >= d_h.samples_per_chan) {
if (!d_repeat) {
// if nothing was read at all, say we're done.
- return i ? i : -1;
+ return items ? produced : -1;
}
if (sf_seek(d_fp, 0, SEEK_SET) == -1) {
@@ -111,14 +116,18 @@ int wavfile_source_impl::work(int noutput_items,
d_sample_idx = 0;
}
- sf_read_float(d_fp, &sample[0], d_h.nchans);
- for (int chan = 0; chan < d_h.nchans; chan++) {
- if (chan < n_out_chans) {
- out[chan][i] = sample[chan];
+ samples = sf_read_float(d_fp, &d_buffer[0], d_h.nchans * s_items_size);
+ items = (int)samples / d_h.nchans;
+ for (int n = 0; n < items; n++) {
+ for (int chan = 0; chan < d_h.nchans; chan++) {
+ if (chan < n_out_chans) {
+ out[chan][n + produced] = d_buffer[chan + (n * d_h.nchans)];
+ }
}
}
- d_sample_idx++;
+ produced += items;
+ d_sample_idx += items;
// We're not going to deal with handling corrupt wav files,
// so if they give us any trouble they won't be processed.
@@ -126,18 +135,18 @@ int wavfile_source_impl::work(int noutput_items,
errnum = sf_error(d_fp);
if (errnum) {
- if (i == 0) {
+ if (items == 0) {
GR_LOG_ERROR(
d_logger,
boost::format("WAV file has corrupted header or I/O error, %s") %
sf_error_number(errnum));
return -1;
}
- return i;
+ return produced;
}
}
- return noutput_items;
+ return produced;
}
} /* namespace blocks */
diff --git a/gr-blocks/lib/wavfile_source_impl.h b/gr-blocks/lib/wavfile_source_impl.h
index 9554feab67..48a3b04f6a 100644
--- a/gr-blocks/lib/wavfile_source_impl.h
+++ b/gr-blocks/lib/wavfile_source_impl.h
@@ -26,6 +26,10 @@ private:
wav_header_info d_h;
long long d_sample_idx;
+ std::vector<float> d_buffer;
+
+ static constexpr int s_items_size = 1024;
+ static constexpr int s_max_channels = 24;
public:
wavfile_source_impl(const char* filename, bool repeat);