+++ /dev/null
-/*
- Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include <stdexcept>
-#include <iostream>
-#include <iomanip>
-#include <getopt.h>
-#include <sndfile.h>
-#include <boost/filesystem.hpp>
-#include "lib/film.h"
-#include "lib/cross.h"
-
-using namespace std;
-using namespace boost;
-
-void
-help (string n)
-{
- cerr << "Syntax: " << n << " [--help] [--chop-audio-start] [--chop-audio-end] --film <film>\n";
-}
-
-void
-sox (vector<string> const & audio_files, string const & process)
-{
- for (vector<string>::const_iterator i = audio_files.begin(); i != audio_files.end(); ++i) {
- stringstream cmd;
- cmd << "sox \"" << *i << "\" -t wav \"" << *i << ".tmp\" " << process;
- cout << "> " << cmd.str() << "\n";
- int r = ::system (cmd.str().c_str());
- if (r == -1 || WEXITSTATUS (r) != 0) {
- cerr << "fixlengths: call to sox failed.\n";
- exit (EXIT_FAILURE);
- }
- filesystem::rename (*i + ".tmp", *i);
- }
-}
-
-int main (int argc, char* argv[])
-{
- string film_dir;
- bool chop_audio_start = false;
- bool chop_audio_end = false;
- bool pad_audio_end = false;
-
- while (1) {
- static struct option long_options[] = {
- { "help", no_argument, 0, 'h' },
- { "chop-audio-start", no_argument, 0, 'c' },
- { "chop-audio-end", no_argument, 0, 'd' },
- { "pad-audio-end", no_argument, 0, 'p' },
- { "film", required_argument, 0, 'f' },
- { 0, 0, 0, 0 }
- };
-
- int option_index = 0;
- int c = getopt_long (argc, argv, "hcf:", long_options, &option_index);
-
- if (c == -1) {
- break;
- }
-
- switch (c) {
- case 'h':
- help (argv[0]);
- exit (EXIT_SUCCESS);
- case 'c':
- chop_audio_start = true;
- break;
- case 'd':
- chop_audio_end = true;
- break;
- case 'p':
- pad_audio_end = true;
- break;
- case 'f':
- film_dir = optarg;
- break;
- }
- }
-
- if (film_dir.empty ()) {
- help (argv[0]);
- exit (EXIT_FAILURE);
- }
-
- dvdomatic_setup ();
-
- Film* film = 0;
- try {
- film = new Film (film_dir, true);
- } catch (std::exception& e) {
- cerr << argv[0] << ": error reading film `" << film_dir << "' (" << e.what() << ")\n";
- exit (EXIT_FAILURE);
- }
-
- /* XXX: hack */
- int video_frames = 0;
- for (filesystem::directory_iterator i = filesystem::directory_iterator (film->j2k_dir()); i != filesystem::directory_iterator(); ++i) {
- ++video_frames;
- }
-
- float const video_length = video_frames / film->frames_per_second();
- cout << "Video length: " << video_length << " (" << video_frames << " frames at " << film->frames_per_second() << " frames per second).\n";
-
- vector<string> audio_files = film->audio_files ();
- if (audio_files.empty ()) {
- cerr << argv[0] << ": film has no audio files.\n";
- exit (EXIT_FAILURE);
- }
-
- sf_count_t audio_frames = 0;
- int audio_sample_rate = 0;
-
- for (vector<string>::iterator i = audio_files.begin(); i != audio_files.end(); ++i) {
- SF_INFO info;
- info.format = 0;
- SNDFILE* sf = sf_open (i->c_str(), SFM_READ, &info);
- if (sf == 0) {
- cerr << argv[0] << ": could not open WAV file for reading.\n";
- exit (EXIT_FAILURE);
- }
-
- if (audio_frames == 0) {
- audio_frames = info.frames;
- }
-
- if (audio_sample_rate == 0) {
- audio_sample_rate = info.samplerate;
- }
-
- if (audio_frames != info.frames) {
- cerr << argv[0] << ": audio files have differing lengths.\n";
- exit (EXIT_FAILURE);
- }
-
- if (audio_sample_rate != info.samplerate) {
- cerr << argv[0] << ": audio files have differing sample rates.\n";
- exit (EXIT_FAILURE);
- }
-
- sf_close (sf);
- }
-
- float const audio_length = audio_frames / float (audio_sample_rate);
-
- cout << "Audio length: " << audio_length << " (" << audio_frames << " frames at " << audio_sample_rate << " frames per second).\n";
-
- cout << "\n";
-
- if (audio_length > video_length) {
- cout << setprecision (3);
- cout << "Audio " << (audio_length - video_length) << "s longer than video.\n";
-
- float const delta = audio_length - video_length;
- int const delta_samples = delta * audio_sample_rate;
-
- if (chop_audio_start) {
- cout << "Chopping difference off the start of the audio.\n";
-
- stringstream s;
- s << "trim " << delta_samples << "s";
- sox (audio_files, s.str ());
-
- } else if (chop_audio_end) {
- cout << "Chopping difference off the end of the audio.\n";
-
- stringstream s;
- s << "reverse trim " << delta_samples << "s reverse";
- sox (audio_files, s.str ());
-
- } else {
- cout << "Re-run with --chop-audio-start or --chop-audio-end, perhaps.\n";
- }
-
- } else if (audio_length < video_length) {
- cout << setprecision (3);
- cout << "Audio " << (video_length - audio_length) << "s shorter than video.\n";
-
- if (pad_audio_end) {
-
- float const delta = video_length - audio_length;
- int const delta_samples = delta * audio_sample_rate;
- stringstream s;
- s << "pad 0 " << delta_samples << "s";
- sox (audio_files, s.str ());
-
- } else {
- cout << "Re-run with --pad-audio-end, perhaps.\n";
- }
- }
-
-
- return 0;
-}