21 #include "libardour-config.h"
35 #include <samplerate.h>
37 #include <glib/gstdio.h>
40 #include <boost/scoped_array.hpp>
41 #include <boost/shared_array.hpp>
121 Session::get_paths_for_new_sources (
bool ,
const string& import_file_path, uint32_t channels)
123 vector<string> new_paths;
126 for (uint32_t n = 0; n < channels; ++n) {
128 const DataType type = SMFSource::safe_midi_file_extension (import_file_path) ? DataType::MIDI : DataType::AUDIO;
135 filepath = new_midi_source_path (mchn_name);
137 filepath = new_midi_source_path (basename);
140 case DataType::AUDIO:
141 filepath = new_audio_source_path (basename, channels, n,
false,
false);
145 if (filepath.empty()) {
147 return vector<string>();
150 new_paths.push_back (filepath);
160 for (vector<string>::const_iterator i = new_paths.begin();
161 i != new_paths.end(); ++i)
166 error <<
string_compose(
_(
"Could not find a source for %1 even though we are updating this file!"), (*i)) << endl;
170 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
177 Session& sess, uint32_t samplerate,
181 for (vector<string>::const_iterator i = new_paths.begin(); i != new_paths.end(); ++i) {
186 const DataType type = SMFSource::safe_midi_file_extension (*i) ? DataType::MIDI : DataType::AUDIO;
188 source = SourceFactory::createWritable (type, sess,
199 newfiles.push_back(boost::dynamic_pointer_cast<Source>(source));
206 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(source)) != 0) {
215 uint32_t file_samplerate,
216 uint32_t session_samplerate,
220 if (file_samplerate != session_samplerate) {
222 Glib::path_get_basename (path),
223 file_samplerate/1000.0
f,
224 session_samplerate/1000.0
f);
227 return string_compose (
_(
"Copying %1"), Glib::path_get_basename (path));
234 const framecnt_t nframes = ResampledImportableSource::blocksize;
236 uint32_t channels = source->
channels();
241 boost::scoped_array<float> data(
new float[nframes * channels]);
242 vector<boost::shared_array<Sample> > channel_data;
244 for (uint32_t n = 0; n < channels; ++n) {
245 channel_data.push_back(boost::shared_array<Sample>(
new Sample[nframes]));
254 float progress_multiplier = 1;
255 float progress_base = 0;
265 uint32_t read_count = 0;
281 gain = (1 - FLT_EPSILON) / peak;
285 progress_multiplier = 0.5;
297 if ((nread = source->
read (data.get(), nframes)) == 0) {
298 #ifdef PLATFORM_WINDOWS
302 for (chn = 0; chn < channels; ++chn)
303 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0)
314 nfread = nread / channels;
318 for (chn = 0; chn < channels; ++chn) {
321 for (x = chn, n = 0; n < nfread; x += channels, ++n) {
322 channel_data[chn][n] = (
Sample) data[x];
328 for (chn = 0; chn < channels; ++chn) {
329 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(newfiles[chn])) != 0) {
330 afs->
write (channel_data[chn].
get(), nfread);
335 status.
progress = progress_base + progress_multiplier * read_count / (source->
ratio () * source->
length() * channels);
343 uint32_t buf_size = 4;
344 uint8_t* buf = (uint8_t*) malloc (buf_size);
348 assert (newfiles.size() == source->
num_tracks());
351 vector<boost::shared_ptr<Source> >::iterator s = newfiles.begin();
353 for (
unsigned i = 1; i <= source->
num_tracks(); ++i) {
363 uint32_t delta_t = 0;
368 gint note_id_ignored;
372 int ret = source->
read_event (&delta_t, &size, &buf, ¬e_id_ignored);
374 if (size > buf_size) {
426 }
catch (exception& e) {
443 ::g_unlink (fs->
path().c_str());
454 typedef vector<boost::shared_ptr<Source> > Sources;
455 Sources all_new_sources;
458 uint32_t channels = 0;
462 for (vector<string>::iterator p = status.
paths.begin();
467 std::auto_ptr<Evoral::SMF> smf_reader;
468 const DataType type = SMFSource::safe_midi_file_extension (*p) ? DataType::MIDI : DataType::AUDIO;
470 if (type == DataType::AUDIO) {
482 smf_reader = std::auto_ptr<Evoral::SMF>(
new Evoral::SMF());
483 smf_reader->open(*p);
484 channels = smf_reader->num_tracks();
486 error <<
_(
"Import: error opening MIDI file") <<
endmsg;
493 error <<
_(
"Import: file contains no channels.") <<
endmsg;
503 fatal <<
"THIS IS NOT IMPLEMENTED YET, IT SHOULD NEVER GET CALLED!!! DYING!" <<
endmsg;
510 std::copy (newfiles.begin(), newfiles.end(), std::back_inserter(all_new_sources));
516 for (Sources::iterator i = newfiles.begin(); i != newfiles.end(); ++i) {
517 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*i)) != 0) {
526 }
else if (smf_reader.get()) {
539 now = localtime (&xnow);
544 for (Sources::iterator x = all_new_sources.begin(); x != all_new_sources.end(); ) {
546 if ((afs = boost::dynamic_pointer_cast<AudioFileSource>(*x)) != 0) {
552 if (
Config->get_auto_analyse_audio()) {
553 Analyser::queue_source_for_analysis (boost::static_pointer_cast<Source>(*x),
false);
566 if (boost::dynamic_pointer_cast<AudioFileSource> (fs)) {
576 if ((smfs = boost::dynamic_pointer_cast<SMFSource>(*x)) != 0 && smfs->
is_empty()) {
577 x = all_new_sources.erase(x);
587 std::copy (all_new_sources.begin(), all_new_sources.end(), std::back_inserter(status.
sources));
592 error <<
_(
"Failed to remove some files after failed/cancelled import operation") <<
endmsg;
LIBPBD_API Transmitter fatal
int read_event(uint32_t *delta_t, uint32_t *size, uint8_t **buf) const
PBD::Signal0< void > DropReferences
int prepare_for_peakfile_writes()
static void remove_file_source(boost::shared_ptr< Source > source)
Session & session() const
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
void mark_immutable_except_write()
static bool create_mono_sources_for_writing(const vector< string > &new_paths, Session &sess, uint32_t samplerate, vector< boost::shared_ptr< Source > > &newfiles, framepos_t timeline_position)
virtual void update_length(framecnt_t)
static bool map_existing_mono_sources(const vector< string > &new_paths, Session &, uint32_t, vector< boost::shared_ptr< Source > > &newfiles, Session *session)
framecnt_t samplerate() const
LIBARDOUR_API compute_peak_t compute_peak
LIBPBD_API Transmitter error
LIBARDOUR_API PBD::PropertyDescriptor< bool > gain
virtual float ratio() const
static void write_audio_data_to_new_files(ImportableSource *source, ImportStatus &status, vector< boost::shared_ptr< Source > > &newfiles)
static string compose_status_message(const string &path, uint32_t file_samplerate, uint32_t session_samplerate, uint32_t, uint32_t)
void drop_model(const Glib::Threads::Mutex::Lock &lock)
std::ostream & endmsg(std::ostream &ostr)
boost::shared_ptr< AudioFileSource > audio_source_by_path_and_channel(const std::string &, uint16_t) const
virtual void set_timeline_position(framepos_t pos)
static Beats ticks_at_rate(uint64_t ticks, uint32_t ppqn)
LIBARDOUR_API RCConfiguration * Config
virtual framecnt_t read(Sample *buffer, framecnt_t nframes)=0
uint16_t num_tracks() const
virtual bool clamped_at_unity() const =0
virtual uint32_t channels() const =0
Beats round_up_to_beat() const
void done_with_peakfile_writes(bool done=true)
int seek_to_track(int track)
virtual void seek(framepos_t pos)=0
void mark_streaming_write_completed(const Lock &lock)
LIBPBD_API Transmitter info
void append_event_beats(const Lock &lock, const Evoral::Event< Evoral::Beats > &ev)
bool replace_existing_source
Glib::Threads::Mutex & mutex()
LIBPBD_API Glib::ustring basename_nosuffix(Glib::ustring)
const std::string & path() const
virtual void mark_streaming_write_started(const Lock &lock)
virtual bool clamped_at_unity() const =0
virtual framecnt_t length() const =0
virtual framepos_t natural_position() const =0
LIBARDOUR_API PBD::PropertyDescriptor< Evoral::Beats > length_beats
virtual framecnt_t write(Sample *src, framecnt_t cnt)
static void write_midi_data_to_new_files(Evoral::SMF *source, ImportStatus &status, vector< boost::shared_ptr< Source > > &newfiles)
LIBARDOUR_API apply_gain_to_buffer_t apply_gain_to_buffer
std::vector< std::string > paths
virtual framecnt_t samplerate() const =0
std::string string_compose(const std::string &fmt, const T1 &o1)
virtual int update_header(framepos_t when, struct tm &, time_t)=0
static boost::shared_ptr< ImportableSource > open_importable_source(const string &path, framecnt_t samplerate, ARDOUR::SrcQuality quality)
framecnt_t samplerate() const