diff options
| author | Carl Hetherington <cth@carlh.net> | 2012-11-15 22:26:16 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2012-11-15 22:26:16 +0000 |
| commit | 4fbd1901fdabc829cfa7e7d4d0c1272bba87033c (patch) | |
| tree | 416701b4a2923cdc16983311239bd311282e8438 /src/lib/external_audio_decoder.cc | |
| parent | f5c40275a2dc444c295a547dfedcd8f9eee2bcb2 (diff) | |
Untested external audio support; AB transcodes still broken.
Diffstat (limited to 'src/lib/external_audio_decoder.cc')
| -rw-r--r-- | src/lib/external_audio_decoder.cc | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/lib/external_audio_decoder.cc b/src/lib/external_audio_decoder.cc new file mode 100644 index 000000000..99dd1ded0 --- /dev/null +++ b/src/lib/external_audio_decoder.cc @@ -0,0 +1,87 @@ +#include <sndfile.h> +#include "external_audio_decoder.h" +#include "film.h" +#include "exceptions.h" + +using std::vector; +using std::string; +using std::min; +using boost::shared_ptr; + +ExternalAudioDecoder::ExternalAudioDecoder (shared_ptr<Film> f, shared_ptr<const Options> o, Job* j) + : Decoder (f, o, j) + , AudioDecoder (f, o, j) +{ + +} + +bool +ExternalAudioDecoder::pass () +{ + vector<string> const files = _film->external_audio (); + + int N = 0; + for (size_t i = 0; i < files.size(); ++i) { + if (!files[i].empty()) { + N = i + 1; + } + } + + if (N == 0) { + return true; + } + + bool first = true; + sf_count_t frames = 0; + + vector<SNDFILE*> sndfiles; + for (vector<string>::const_iterator i = files.begin(); i != files.end(); ++i) { + if (i->empty ()) { + sndfiles.push_back (0); + } else { + SF_INFO info; + SNDFILE* s = sf_open (i->c_str(), SFM_READ, &info); + if (!s) { + throw DecodeError ("could not open external audio file for reading"); + } + + if (info.channels != 1) { + throw DecodeError ("external audio files must be mono"); + } + + sndfiles.push_back (s); + + if (first) { + /* XXX: nasty magic value */ + AudioStream st ("DVDOMATIC-EXTERNAL", -1, info.samplerate, av_get_default_channel_layout (info.channels)); + _audio_streams.push_back (st); + _audio_stream = st; + frames = info.frames; + first = false; + } else { + if (info.frames != frames) { + throw DecodeError ("external audio files have differing lengths"); + } + } + } + } + + sf_count_t const block = 65536; + + shared_ptr<AudioBuffers> audio (new AudioBuffers (_audio_stream.get().channels(), block)); + 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); + } + } + + Audio (audio); + frames -= this_time; + } + + return true; +} |
