Fix broken external audio support.
authorCarl Hetherington <cth@carlh.net>
Sun, 28 Apr 2013 15:23:35 +0000 (16:23 +0100)
committerCarl Hetherington <cth@carlh.net>
Sun, 28 Apr 2013 15:23:35 +0000 (16:23 +0100)
ChangeLog
src/lib/sndfile_decoder.cc
src/lib/sndfile_decoder.h

index 129d148e9f76e1fb2cd97cf5afaad7557df44255..64db7a3ec2629f5f6f44800f5d9f35c6a7caadfc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-04-28  Carl Hetherington  <cth@carlh.net>
+
+       * Fix broken external audio support.
+
 2013-04-24  Carl Hetherington  <cth@carlh.net>
 
        * Allow use of existing empty directories for new films (without
index af59c049c31dba1acc59d9dad4132a2de5b8dcaa..fdaf2eeaaf4397ad5d1cb1430ebc6d006607a5b7 100644 (file)
@@ -36,15 +36,12 @@ using boost::optional;
 SndfileDecoder::SndfileDecoder (shared_ptr<Film> f, DecodeOptions o)
        : Decoder (f, o)
        , AudioDecoder (f, o)
+       , _done (0)
+       , _frames (0)
 {
-       sf_count_t frames;
-       vector<SNDFILE*> sf = open_files (frames);
-       close_files (sf);
-}
-
-vector<SNDFILE*>
-SndfileDecoder::open_files (sf_count_t & frames)
-{
+       _done = 0;
+       _frames = 0;
+       
        vector<string> const files = _film->external_audio ();
 
        int N = 0;
@@ -55,16 +52,14 @@ SndfileDecoder::open_files (sf_count_t & frames)
        }
 
        if (N == 0) {
-               return vector<SNDFILE*> ();
+               return;
        }
 
        bool first = true;
-       frames = 0;
        
-       vector<SNDFILE*> sndfiles;
        for (size_t i = 0; i < (size_t) N; ++i) {
                if (files[i].empty ()) {
-                       sndfiles.push_back (0);
+                       _sndfiles.push_back (0);
                } else {
                        SF_INFO info;
                        SNDFILE* s = sf_open (files[i].c_str(), SFM_READ, &info);
@@ -76,7 +71,7 @@ SndfileDecoder::open_files (sf_count_t & frames)
                                throw DecodeError (_("external audio files must be mono"));
                        }
                        
-                       sndfiles.push_back (s);
+                       _sndfiles.push_back (s);
 
                        if (first) {
                                shared_ptr<SndfileStream> st (
@@ -87,60 +82,47 @@ SndfileDecoder::open_files (sf_count_t & frames)
                                
                                _audio_streams.push_back (st);
                                _audio_stream = st;
-                               frames = info.frames;
+                               _frames = info.frames;
                                first = false;
                        } else {
-                               if (info.frames != frames) {
+                               if (info.frames != _frames) {
                                        throw DecodeError (_("external audio files have differing lengths"));
                                }
                        }
                }
        }
-
-       return sndfiles;
 }
 
 bool
 SndfileDecoder::pass ()
 {
-       sf_count_t frames;
-       vector<SNDFILE*> sndfiles = open_files (frames);
-       if (sndfiles.empty()) {
-               return true;
-       }
-
        /* Do things in half second blocks as I think there may be limits
           to what FFmpeg (and in particular the resampler) can cope with.
        */
        sf_count_t const block = _audio_stream->sample_rate() / 2;
        shared_ptr<AudioBuffers> audio (new AudioBuffers (_audio_stream->channels(), block));
-       sf_count_t done = 0;
-       while (frames > 0) {
-               sf_count_t const this_time = min (block, frames);
-               for (size_t i = 0; i < sndfiles.size(); ++i) {
-                       if (!sndfiles[i]) {
-                               audio->make_silent (i);
-                       } else {
-                               sf_read_float (sndfiles[i], audio->data(i), block);
-                       }
+       sf_count_t const this_time = min (block, _frames - _done);
+       for (size_t i = 0; i < _sndfiles.size(); ++i) {
+               if (!_sndfiles[i]) {
+                       audio->make_silent (i);
+               } else {
+                       sf_read_float (_sndfiles[i], audio->data(i), this_time);
                }
-
-               audio->set_frames (this_time);
-               Audio (audio, double(done) / _audio_stream->sample_rate());
-               done += this_time;
-               frames -= this_time;
        }
 
-       close_files (sndfiles);
+       audio->set_frames (this_time);
+       Audio (audio, double(_done) / _audio_stream->sample_rate());
+       _done += this_time;
 
-       return true;
+       return (_done == _frames);
 }
 
-void
-SndfileDecoder::close_files (vector<SNDFILE*> const & sndfiles)
+SndfileDecoder::~SndfileDecoder ()
 {
-       for (size_t i = 0; i < sndfiles.size(); ++i) {
-               sf_close (sndfiles[i]);
+       for (size_t i = 0; i < _sndfiles.size(); ++i) {
+               if (_sndfiles[i]) {
+                       sf_close (_sndfiles[i]);
+               }
        }
 }
 
index e16eab6731e2f23d4bc32e9f4e6dfd1a8c2fced7..9489cb5ec5b56e4a6b076ff0da1360e643a19734 100644 (file)
@@ -45,10 +45,12 @@ class SndfileDecoder : public AudioDecoder
 {
 public:
        SndfileDecoder (boost::shared_ptr<Film>, DecodeOptions);
+       ~SndfileDecoder ();
 
        bool pass ();
 
 private:
-       std::vector<SNDFILE*> open_files (sf_count_t &);
-       void close_files (std::vector<SNDFILE*> const &);
+       std::vector<SNDFILE*> _sndfiles;
+       sf_count_t _done;
+       sf_count_t _frames;
 };