diff options
-rw-r--r-- | gr-blocks/lib/wavfile_sink_impl.cc | 28 | ||||
-rw-r--r-- | gr-blocks/lib/wavfile_sink_impl.h | 4 | ||||
-rw-r--r-- | gr-blocks/lib/wavfile_source_impl.cc | 37 | ||||
-rw-r--r-- | gr-blocks/lib/wavfile_source_impl.h | 4 |
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); |