From bb14132ddfc3d95e90f60373e3431b1e66129f65 Mon Sep 17 00:00:00 2001 From: Benjamin Schulz Date: Wed, 25 Feb 2015 21:09:09 +0100 Subject: [PATCH] changed the way we're looping over the samples. We're now looking only once at each input sample. we're not seeking in the input file. This is required for reading from stdin to work. A small drawback is, that we have to collect all output values in a vector before output. --- src/main.cpp | 31 +++++---------- src/wav2json.cpp | 99 +++++++++++++++++++++++++++++++----------------- src/wav2json.hpp | 2 +- 3 files changed, 75 insertions(+), 57 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 8662fa8..3598847 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -71,27 +71,16 @@ int main(int argc, char* argv[]) return 2; } - for(size_t i = 0; i != options.channels.size(); ++i) - { - wav.seek(0, SEEK_SET); - - Options::Channel channel = options.channels[i]; - - ofs << " \"" << channel << "\":"; - - compute_waveform( - wav, - ofs, - options.samples, - channel, - options.use_db_scale, - options.db_min, - options.db_max, - progress_callback - ); - - ofs << "," << std::endl; - } + compute_waveform( + wav, + ofs, + options.samples, + options.channels, + options.use_db_scale, + options.db_min, + options.db_max, + progress_callback + ); // increase precission for duration ofs << std::fixed; //explicitly use fixed notation diff --git a/src/wav2json.cpp b/src/wav2json.cpp index 79a8d14..33c1d6f 100644 --- a/src/wav2json.cpp +++ b/src/wav2json.cpp @@ -84,15 +84,13 @@ void compute_waveform( const SndfileHandle& wav, std::ostream& output_stream, size_t samples, - Options::Channel channel, + Options::Channels channels, bool use_db_scale, float db_min, float db_max, progress_callback_t progress_callback ) { - output_stream << "["; - using std::size_t; using std::cerr; using std::endl; @@ -113,20 +111,34 @@ void compute_waveform( // temp buffer for samples from audio file std::vector block(samples_per_pixel); - if ( - (channel == Options::MID || - channel == Options::SIDE || - channel == Options::RIGHT|| - channel == Options::MIN || - channel == Options::MAX - ) && - wav.channels() == 1 - ) + // filter out channels, that require more channels than the wav file has + channels.erase( + std::remove_if(channels.begin(), channels.end(), [&wav](Options::Channel channel){ + if ((channel == Options::MID || + channel == Options::SIDE || + channel == Options::RIGHT|| + channel == Options::MIN || + channel == Options::MAX) && + wav.channels() == 1 + ) + { + std::cerr << "Warning: your trying to generate output for channel '" << channel << "', but the input has only one channel. removing requested channel." << std::endl; + return true; + } + return false; + }), + channels.end() + ); + + if (channels.empty()) { - std::cerr << "Warning: your trying to generate output for channel '" << channel << "', but the input has only one channel. falling back to the left channel." << std::endl; - channel = Options::LEFT; + std::cerr << "Warning: there are no channels left to process, aborting." << endl; + return; } + // create one vector of floats for each requested channel + std::vector > output_values( channels.size() ); + // https://github.com/beschulz/wav2json/pull/7 // http://www.mega-nerd.com/libsndfile/api.html#note2 const_cast(wav).command(SFC_SET_SCALE_FLOAT_INT_READ, 0, SF_TRUE); @@ -138,38 +150,55 @@ void compute_waveform( */ for (size_t x = 0; x < samples; ++x) { - // read frames + // read frames sf_count_t n = const_cast(wav).readf(&block[0], frames_per_pixel) * wav.channels(); assert(n <= (sf_count_t)block.size()); - // find min and max - sample_type max(0); - for (int i=0; i::value ), db_min, db_max, 0, 1): + map2range( max, 0, sample_scale::value, 0, 1); + + // print progress + if ( x%(progress_divisor) == 0 ) + { + if ( progress_callback && !progress_callback( 100*x/samples ) ) + return; + } - float y = use_db_scale? - map2range( float2db(max / (float)sample_scale::value ), db_min, db_max, 0, 1): - map2range( max, 0, sample_scale::value, 0, 1); + output_values[channel_idx].push_back(y); + } + } - output_stream << y; - if (x != samples-1) //only write out comma, if this is not the last sample - output_stream << ","; + // finally output the collected values + for(size_t channel_idx = 0; channel_idx != channels.size(); ++channel_idx) + { + Options::Channel channel = channels[channel_idx]; - // print progress - if ( x%(progress_divisor) == 0 ) + output_stream << " \"" << channel << "\": ["; + for (size_t i = 0; i != output_values[channel_idx].size(); ++i) { - if ( progress_callback && !progress_callback( 100*x/samples ) ) - return; + output_stream << output_values[channel_idx][i]; + if (i != output_values[channel_idx].size()-1) + output_stream << ","; // only output comma, if not the last ellement } + output_stream << "]," << endl; } - + // call the progress callback if ( progress_callback && !progress_callback( 100 ) ) return; - - output_stream << "]"; } diff --git a/src/wav2json.hpp b/src/wav2json.hpp index 383b00d..94d8a73 100644 --- a/src/wav2json.hpp +++ b/src/wav2json.hpp @@ -11,7 +11,7 @@ void compute_waveform( const SndfileHandle& wav, std::ostream& output_stream, size_t samples, - Options::Channel channel, + Options::Channels channels, bool use_db_scale, float db_min, float db_max,