25 #include <glibmm/miscutils.h>
27 #include "audiographer/process_context.h"
28 #include "audiographer/general/chunker.h"
29 #include "audiographer/general/interleaver.h"
30 #include "audiographer/general/normalizer.h"
31 #include "audiographer/general/peak_reader.h"
32 #include "audiographer/general/sample_format_converter.h"
33 #include "audiographer/general/sr_converter.h"
34 #include "audiographer/general/silence_trimmer.h"
35 #include "audiographer/general/threader.h"
36 #include "audiographer/sndfile/tmp_file.h"
37 #include "audiographer/sndfile/sndfile_writer.h"
55 ExportGraphBuilder::ExportGraphBuilder (
Session const & session)
71 for (ChannelMap::iterator it =
channels.begin(); it !=
channels.end(); ++it) {
72 Sample const * process_buffer = 0;
73 it->first->read (process_buffer, frames);
74 ConstProcessContext<Sample> context(process_buffer, frames, 1);
75 if (last_cycle) { context().set_flag (ProcessContext<Sample>::EndOfInput); }
76 it->second->process (context);
86 if ((*it)->process()) {
101 max = std::max(max, (*it)->get_normalize_cycle_count());
126 for(ExportChannelConfiguration::ChannelList::const_iterator it = channels.begin();
127 it != channels.end(); ++it) {
148 typedef std::list<boost::shared_ptr<ExportChannelConfiguration> > ConfigList;
149 ConfigList file_configs;
150 new_config.
channel_config->configurations_for_files (file_configs);
153 for (ConfigList::iterator it = file_configs.begin(); it != file_configs.end(); ++it, ++chan) {
158 copy.
filename->include_channel =
true;
170 it->add_child (config);
195 init_writer (int_writer);
204 init_writer (short_writer);
211 filenames.push_back (new_config.
filename);
217 return get_real_format (config) == get_real_format (other_config);
231 unsigned channels = config.channel_config->get_n_chans();
232 int format = get_real_format (config);
233 config.filename->set_channel_config(config.channel_config);
234 string filename = config.filename->get_path (config.format);
243 while (filenames.size()) {
245 PBD::copy_file (orig_path, filename->get_path (config.format).c_str());
246 filenames.pop_front();
268 int actual_data_width = 8 *
sizeof(
Sample);
278 if (data_width == 8 || data_width == 16) {
279 return short_converter;
280 }
else if (data_width == 24 || data_width == 32) {
281 return int_converter;
283 return float_converter;
290 for (boost::ptr_list<Encoder>::iterator it = children.begin(); it != children.end(); ++it) {
291 if (*it == new_config) {
292 it->add_child (new_config);
297 children.push_back (
new Encoder());
298 Encoder & encoder = children.back();
300 if (data_width == 8 || data_width == 16) {
301 short_converter->add_output (encoder.
init<
short> (new_config));
302 }
else if (data_width == 24 || data_width == 32) {
303 int_converter->add_output (encoder.
init<
int> (new_config));
305 float_converter->add_output (encoder.
init<
Sample> (new_config));
312 return config.format->sample_format() == other_config.
format->sample_format();
321 tmpfile_path = Glib::build_filename(tmpfile_path,
"XXXXXX");
322 std::vector<char> tmpfile_path_buf(tmpfile_path.size() + 1);
323 std::copy(tmpfile_path.begin(), tmpfile_path.end(), tmpfile_path_buf.begin());
324 tmpfile_path_buf[tmpfile_path.size()] =
'\0';
357 for (boost::ptr_list<SFC>::iterator it = children.begin(); it != children.end(); ++it) {
358 if (*it == new_config) {
359 it->add_child (new_config);
364 children.push_back (
new SFC (parent, new_config, max_frames_out));
365 threader->add_output (children.back().sink());
371 return config.format->normalize() == other_config.
format->normalize() &&
372 config.format->normalize_target() == other_config.
format->normalize_target();
378 return static_cast<unsigned>(std::ceil(static_cast<float>(tmp_file->get_frames_written()) /
385 framecnt_t frames_read = tmp_file->read (*buffer);
386 return frames_read != buffer->frames();
392 normalizer->set_peak (peak_reader->get_peak());
393 tmp_file->seek (0, SEEK_SET);
394 tmp_file->add_output (normalizer);
395 parent.normalizers.push_back (
this);
421 if (new_config.
format->normalize()) {
422 add_child_to_list (new_config, normalized_children);
424 add_child_to_list (new_config, children);
432 for (
typename boost::ptr_list<T>::iterator it = list.begin(); it != list.end(); ++it) {
433 if (*it == new_config) {
434 it->add_child (new_config);
439 list.push_back (
new T (parent, new_config, max_frames_out));
440 converter->add_output (list.back().sink ());
446 return config.format->sample_rate() == other_config.
format->sample_rate();
473 return silence_trimmer;
479 for (boost::ptr_list<SRC>::iterator it = children.begin(); it != children.end(); ++it) {
480 if (*it == new_config) {
481 it->add_child (new_config);
486 children.push_back (
new SRC (parent, new_config, max_frames_in));
487 silence_trimmer->add_output (children.back().sink());
517 if (chan_count > 0) {
525 for (ChannelList::const_iterator it = channel_list.begin(); it != channel_list.end(); ++it, ++chan) {
526 ChannelMap::iterator map_it = channel_map.find (*it);
527 if (map_it == channel_map.end()) {
528 std::pair<ChannelMap::iterator, bool> result_pair =
529 channel_map.insert (std::make_pair (*it,
IdentityVertexPtr (
new IdentityVertex<Sample> ())));
530 assert (result_pair.second);
531 map_it = result_pair.first;
533 map_it->second->add_output (
interleaver->input (chan));
542 assert (*
this == new_config);
544 for (boost::ptr_list<SilenceHandler>::iterator it = children.begin(); it != children.end(); ++it) {
545 if (*it == new_config) {
546 it->add_child (new_config);
551 children.push_back (
new SilenceHandler (parent, new_config, max_frames_out));
552 chunker->add_output (children.back().sink ());
framecnt_t max_frames_out
framecnt_t nominal_frame_rate() const
ShortConverterPtr short_converter
FloatWriterPtr float_writer
IntConverterPtr int_converter
bool operator==(FileSpec const &other_config) const
framecnt_t process_buffer_frames
SilenceTrimmerPtr silence_trimmer
unsigned get_normalize_cycle_count() const
pframes_t samples_per_cycle() const
boost::shared_ptr< AudioGrapher::SampleFormatConverter< int > > IntConverterPtr
void add_child(FileSpec const &new_config)
std::map< ExportChannelPtr, IdentityVertexPtr > ChannelMap
void add_split_config(FileSpec const &config)
void add_child(FileSpec const &new_config)
ExportFormatSpecPtr format
std::list< ExportChannelPtr > ChannelList
boost::shared_ptr< ExportTimespan > timespan
ExportChannelConfigPtr channel_config
ChannelConfigList channel_configs
void start_post_processing()
bool copy_file(const std::string &from_path, const std::string &to_path)
void set_current_timespan(boost::shared_ptr< ExportTimespan > span)
PeakReaderPtr peak_reader
SRC(ExportGraphBuilder &parent, FileSpec const &new_config, framecnt_t max_frames)
unsigned get_normalize_cycle_count() const
bool process()
Returns true when finished.
bool operator==(FileSpec const &other_config) const
void add_child(FileSpec const &new_config)
bool operator==(FileSpec const &other_config) const
SilenceHandler(ExportGraphBuilder &parent, FileSpec const &new_config, framecnt_t max_frames)
PBD::ScopedConnection post_processing_connection
uint32_t hardware_concurrency()
Normalizer(ExportGraphBuilder &parent, FileSpec const &new_config, framecnt_t max_frames)
int process(framecnt_t frames, bool last_cycle)
boost::shared_ptr< AudioGrapher::SampleFormatConverter< short > > ShortConverterPtr
const std::string export_path() const
FloatConverterPtr float_converter
ExportFilenamePtr filename
void copy_files(std::string orig_path)
Glib::ThreadPool thread_pool
ChannelConfig(ExportGraphBuilder &parent, FileSpec const &new_config, ChannelMap &channel_map)
framecnt_t max_frames_out
bool operator==(FileSpec const &other_config) const
boost::shared_ptr< AudioGrapher::Sink< T > > init(FileSpec const &new_config)
void add_child(FileSpec const &new_config)
bool operator==(FileSpec const &other_config) const
const SessionDirectory & session_directory() const
void add_config(FileSpec const &config)
std::list< Normalizer * > normalizers
void add_child_to_list(FileSpec const &new_config, boost::ptr_list< T > &list)
framecnt_t max_frames_out
SFC(ExportGraphBuilder &, FileSpec const &new_config, framecnt_t max_frames)
InterleaverPtr interleaver
static int get_real_format(FileSpec const &config)
void add_child(FileSpec const &new_config)
void init_writer(boost::shared_ptr< AudioGrapher::SndfileWriter< T > > &writer)
boost::shared_ptr< AudioGrapher::SampleFormatConverter< Sample > > FloatConverterPtr
bool operator==(FileSpec const &other_config) const
int sndfile_data_width(int format)
void add_child(FileSpec const &new_config)