Remove 16 year old session-import prototype (2/2)
This was based on Arodur 2.x sessions modifying XML which no longer applies (and non functioning GUI).
This commit is contained in:
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Sakari Bergen <sakari.bergen@beatwaves.net>
|
||||
* Copyright (C) 2009-2010 Carl Hetherington <carl@carlh.net>
|
||||
* Copyright (C) 2009-2012 David Robillard <d@drobilla.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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
#include "pbd/xml++.h"
|
||||
#include "pbd/id.h"
|
||||
|
||||
#include "ardour/element_importer.h"
|
||||
#include "ardour/element_import_handler.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class AudioRegionImportHandler;
|
||||
class AudioRegionImporter;
|
||||
class AudioPlaylistImporter;
|
||||
class Session;
|
||||
|
||||
class LIBARDOUR_API AudioPlaylistImportHandler : public ElementImportHandler
|
||||
{
|
||||
public:
|
||||
typedef std::shared_ptr<AudioPlaylistImporter> PlaylistPtr;
|
||||
typedef std::list<PlaylistPtr> PlaylistList;
|
||||
|
||||
AudioPlaylistImportHandler (XMLTree const & source, Session & session, AudioRegionImportHandler & region_handler, const char * nodename = "Playlists");
|
||||
virtual ~AudioPlaylistImportHandler () {}
|
||||
virtual std::string get_info () const;
|
||||
|
||||
void get_regions (XMLNode const & node, ElementList & list) const;
|
||||
void update_region_id (XMLProperty* id_prop);
|
||||
|
||||
void playlists_by_diskstream (PBD::ID const & id, PlaylistList & list) const;
|
||||
|
||||
protected:
|
||||
AudioRegionImportHandler & region_handler;
|
||||
};
|
||||
|
||||
class LIBARDOUR_API UnusedAudioPlaylistImportHandler : public AudioPlaylistImportHandler
|
||||
{
|
||||
public:
|
||||
UnusedAudioPlaylistImportHandler (XMLTree const & source, Session & session, AudioRegionImportHandler & region_handler) :
|
||||
AudioPlaylistImportHandler (source, session, region_handler, "UnusedPlaylists") { }
|
||||
std::string get_info () const;
|
||||
};
|
||||
|
||||
class LIBARDOUR_API AudioPlaylistImporter : public ElementImporter
|
||||
{
|
||||
public:
|
||||
AudioPlaylistImporter (XMLTree const & source, Session & session, AudioPlaylistImportHandler & handler, XMLNode const & node);
|
||||
AudioPlaylistImporter (AudioPlaylistImporter const & other);
|
||||
~AudioPlaylistImporter ();
|
||||
|
||||
std::string get_info () const;
|
||||
|
||||
void set_diskstream (PBD::ID const & id);
|
||||
PBD::ID const & orig_diskstream () const { return orig_diskstream_id; }
|
||||
|
||||
protected:
|
||||
bool _prepare_move ();
|
||||
void _cancel_move ();
|
||||
void _move ();
|
||||
|
||||
private:
|
||||
typedef std::list<std::shared_ptr<AudioRegionImporter> > RegionList;
|
||||
|
||||
void populate_region_list ();
|
||||
|
||||
AudioPlaylistImportHandler & handler;
|
||||
XMLNode const & orig_node;
|
||||
XMLNode xml_playlist;
|
||||
PBD::ID orig_diskstream_id;
|
||||
PBD::ID diskstream_id;
|
||||
RegionList regions;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 Sakari Bergen <sakari.bergen@beatwaves.net>
|
||||
* Copyright (C) 2009-2012 David Robillard <d@drobilla.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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
|
||||
#include "pbd/xml++.h"
|
||||
#include "pbd/id.h"
|
||||
#include "ardour/element_importer.h"
|
||||
#include "ardour/element_import_handler.h"
|
||||
#include "ardour/import_status.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class Region;
|
||||
class Session;
|
||||
class Source;
|
||||
|
||||
class LIBARDOUR_API AudioRegionImportHandler : public ElementImportHandler
|
||||
{
|
||||
public:
|
||||
// Inerface implementation
|
||||
AudioRegionImportHandler (XMLTree const & source, Session & session);
|
||||
std::string get_info () const;
|
||||
|
||||
void create_regions_from_children (XMLNode const & node, ElementList & list);
|
||||
|
||||
// Source management
|
||||
bool check_source (std::string const & filename) const;
|
||||
void add_source (std::string const & filename, std::shared_ptr<Source> const & source);
|
||||
std::shared_ptr<Source> const & get_source (std::string const & filename) const;
|
||||
|
||||
// Id management
|
||||
void register_id (PBD::ID & old_id, PBD::ID & new_id);
|
||||
PBD::ID const & get_new_id (PBD::ID & old_id) const;
|
||||
|
||||
private:
|
||||
// Source management
|
||||
typedef std::map<std::string, std::shared_ptr<Source> > SourceMap;
|
||||
typedef std::pair<std::string, std::shared_ptr<Source> > SourcePair;
|
||||
SourceMap sources;
|
||||
|
||||
// Id management
|
||||
typedef std::map<PBD::ID, PBD::ID> IdMap;
|
||||
typedef std::pair<PBD::ID, PBD::ID> IdPair;
|
||||
IdMap id_map;
|
||||
};
|
||||
|
||||
class LIBARDOUR_API AudioRegionImporter : public ElementImporter
|
||||
{
|
||||
public:
|
||||
AudioRegionImporter (XMLTree const & source, Session & session, AudioRegionImportHandler & handler, XMLNode const & node);
|
||||
~AudioRegionImporter ();
|
||||
|
||||
// Interface implementation
|
||||
std::string get_info () const;
|
||||
ImportStatus * get_import_status () { return &status; }
|
||||
|
||||
// other stuff
|
||||
void add_sources_to_session ();
|
||||
XMLNode const & get_xml ();
|
||||
|
||||
protected:
|
||||
bool _prepare_move ();
|
||||
void _cancel_move ();
|
||||
void _move ();
|
||||
|
||||
private:
|
||||
|
||||
XMLNode xml_region;
|
||||
AudioRegionImportHandler & handler;
|
||||
PBD::ID old_id;
|
||||
PBD::ID id;
|
||||
std::list<std::string> filenames;
|
||||
ImportStatus status;
|
||||
|
||||
bool parse_xml_region ();
|
||||
bool parse_source_xml ();
|
||||
std::string get_sound_dir (XMLTree const & tree);
|
||||
|
||||
void prepare_region ();
|
||||
void prepare_sources ();
|
||||
std::vector<std::shared_ptr<Region> > region;
|
||||
bool region_prepared;
|
||||
bool sources_prepared;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Sakari Bergen <sakari.bergen@beatwaves.net>
|
||||
* Copyright (C) 2009-2014 David Robillard <d@drobilla.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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "pbd/xml++.h"
|
||||
#include "pbd/id.h"
|
||||
|
||||
#include "ardour/element_importer.h"
|
||||
#include "ardour/element_import_handler.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class AudioPlaylistImportHandler;
|
||||
class AudioPlaylistImporter;
|
||||
|
||||
class LIBARDOUR_API AudioTrackImportHandler : public ElementImportHandler
|
||||
{
|
||||
public:
|
||||
AudioTrackImportHandler (XMLTree const & source, Session & session, AudioPlaylistImportHandler & pl_handler);
|
||||
virtual ~AudioTrackImportHandler () {}
|
||||
virtual std::string get_info () const;
|
||||
};
|
||||
|
||||
|
||||
class LIBARDOUR_API AudioTrackImporter : public ElementImporter
|
||||
{
|
||||
public:
|
||||
AudioTrackImporter (XMLTree const & source,
|
||||
Session & session,
|
||||
AudioTrackImportHandler & track_handler,
|
||||
XMLNode const & node,
|
||||
AudioPlaylistImportHandler & pl_handler);
|
||||
~AudioTrackImporter ();
|
||||
|
||||
std::string get_info () const;
|
||||
|
||||
protected:
|
||||
bool _prepare_move ();
|
||||
void _cancel_move ();
|
||||
void _move ();
|
||||
|
||||
private:
|
||||
|
||||
typedef std::shared_ptr<AudioPlaylistImporter> PlaylistPtr;
|
||||
typedef std::list<PlaylistPtr> PlaylistList;
|
||||
|
||||
bool parse_route_xml ();
|
||||
bool parse_io ();
|
||||
|
||||
bool parse_processor (XMLNode & node);
|
||||
bool parse_controllable (XMLNode & node);
|
||||
bool parse_automation (XMLNode & node);
|
||||
bool rate_convert_events (XMLNode & node);
|
||||
|
||||
AudioTrackImportHandler & track_handler;
|
||||
XMLNode xml_track;
|
||||
|
||||
PBD::ID old_ds_id;
|
||||
PBD::ID new_ds_id;
|
||||
|
||||
PlaylistList playlists;
|
||||
AudioPlaylistImportHandler & pl_handler;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 Sakari Bergen <sakari.bergen@beatwaves.net>
|
||||
* Copyright (C) 2009-2010 Carl Hetherington <carl@carlh.net>
|
||||
* Copyright (C) 2009-2017 Paul Davis <paul@linuxaudiosystems.com>
|
||||
* Copyright (C) 2009 David Robillard <d@drobilla.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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "pbd/signals.h"
|
||||
#include "ardour/libardour_visibility.h"
|
||||
#include "ardour/types.h"
|
||||
|
||||
class XMLTree;
|
||||
namespace ARDOUR {
|
||||
|
||||
class Session;
|
||||
class ImportStatus;
|
||||
|
||||
/// Virtual interface class for element importers
|
||||
class LIBARDOUR_API ElementImporter
|
||||
{
|
||||
public:
|
||||
|
||||
ElementImporter (XMLTree const & source, ARDOUR::Session & session);
|
||||
virtual ~ElementImporter ();
|
||||
|
||||
/** Returns the element name
|
||||
* @return the name of the element
|
||||
*/
|
||||
virtual std::string get_name () const { return name; };
|
||||
|
||||
/** Gets a textual representation of the element
|
||||
* @return a textual representation on this specific element
|
||||
*/
|
||||
virtual std::string get_info () const = 0;
|
||||
|
||||
/** Gets import status, if applicable. */
|
||||
virtual ImportStatus * get_import_status () { return 0; }
|
||||
|
||||
/** Prepares to move element
|
||||
*
|
||||
* @return whther or not the element could be prepared for moving
|
||||
*/
|
||||
bool prepare_move ();
|
||||
|
||||
/** Cancels moving of element
|
||||
* If the element has been set to be moved, this cancels the move.
|
||||
*/
|
||||
void cancel_move ();
|
||||
|
||||
/// Moves the element to the taget session
|
||||
void move ();
|
||||
|
||||
/// Check if element is broken. Cannot be moved if broken.
|
||||
bool broken () { return _broken; }
|
||||
|
||||
/// Signal that requests for anew name
|
||||
static PBD::Signal<std::pair<bool, std::string>(std::string, std::string)> Rename;
|
||||
|
||||
/// Signal for ok/cancel prompting
|
||||
static PBD::Signal<bool(std::string)> Prompt;
|
||||
|
||||
protected:
|
||||
|
||||
/** Moves the element to the taget session
|
||||
* In addition to actually adding the element to the session
|
||||
* changing ids, renaming files etc. should be taken care of.
|
||||
*/
|
||||
virtual void _move () = 0;
|
||||
|
||||
/** Should take care of all tasks that need to be done
|
||||
* before moving the element. This includes prompting
|
||||
* the user for more information if necessary.
|
||||
*
|
||||
* @return whether or not the element can be moved
|
||||
*/
|
||||
virtual bool _prepare_move () = 0;
|
||||
|
||||
/// Cancel move
|
||||
virtual void _cancel_move () = 0;
|
||||
|
||||
/// Source XML-tree
|
||||
XMLTree const & source;
|
||||
|
||||
/// Target session
|
||||
ARDOUR::Session & session;
|
||||
|
||||
/// Ture if the element has been prepared and queued for importing
|
||||
bool queued () { return _queued; }
|
||||
|
||||
/// Name of element
|
||||
std::string name;
|
||||
|
||||
/// The sample rate of the session from which we are importing
|
||||
samplecnt_t sample_rate;
|
||||
|
||||
/// Converts timecode time to a string
|
||||
std::string timecode_to_string (Timecode::Time & time) const;
|
||||
|
||||
/// Converts samples so that times match the sessions sample rate
|
||||
samplecnt_t rate_convert_samples (samplecnt_t samples) const;
|
||||
|
||||
/// Converts samples so that times match the sessions sample rate (for straight use in XML)
|
||||
std::string rate_convert_samples (std::string const & samples) const;
|
||||
|
||||
/// Set element broken
|
||||
void set_broken () { _broken = true; }
|
||||
|
||||
private:
|
||||
bool _queued;
|
||||
bool _broken;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Sakari Bergen <sakari.bergen@beatwaves.net>
|
||||
* Copyright (C) 2009-2012 David Robillard <d@drobilla.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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ardour/element_importer.h"
|
||||
#include "ardour/element_import_handler.h"
|
||||
|
||||
#include "pbd/xml++.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class Location;
|
||||
class Session;
|
||||
|
||||
class LIBARDOUR_API LocationImportHandler : public ElementImportHandler
|
||||
{
|
||||
public:
|
||||
LocationImportHandler (XMLTree const & source, Session & session);
|
||||
std::string get_info () const;
|
||||
};
|
||||
|
||||
class LIBARDOUR_API LocationImporter : public ElementImporter
|
||||
{
|
||||
public:
|
||||
LocationImporter (XMLTree const & source, Session & session, LocationImportHandler & handler, XMLNode const & node);
|
||||
~LocationImporter ();
|
||||
|
||||
std::string get_info () const;
|
||||
|
||||
protected:
|
||||
bool _prepare_move ();
|
||||
void _cancel_move ();
|
||||
void _move ();
|
||||
|
||||
private:
|
||||
LocationImportHandler & handler;
|
||||
XMLNode xml_location;
|
||||
Location * location;
|
||||
|
||||
void parse_xml ();
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Sakari Bergen <sakari.bergen@beatwaves.net>
|
||||
* Copyright (C) 2009-2012 David Robillard <d@drobilla.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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "pbd/xml++.h"
|
||||
|
||||
#include "ardour/element_importer.h"
|
||||
#include "ardour/element_import_handler.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class Session;
|
||||
|
||||
class LIBARDOUR_API TempoMapImportHandler : public ElementImportHandler
|
||||
{
|
||||
public:
|
||||
TempoMapImportHandler (XMLTree const & source, Session & session);
|
||||
std::string get_info () const;
|
||||
};
|
||||
|
||||
class LIBARDOUR_API TempoMapImporter : public ElementImporter
|
||||
{
|
||||
private:
|
||||
typedef std::shared_ptr<XMLNode> XMLNodePtr;
|
||||
public:
|
||||
TempoMapImporter (XMLTree const & source, Session & session, XMLNode const & node);
|
||||
|
||||
virtual std::string get_info () const;
|
||||
|
||||
protected:
|
||||
bool _prepare_move ();
|
||||
void _cancel_move ();
|
||||
void _move ();
|
||||
|
||||
private:
|
||||
XMLNode xml_tempo_map;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
@@ -1,270 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2014 David Robillard <d@drobilla.net>
|
||||
* Copyright (C) 2008 Sakari Bergen <sakari.bergen@beatwaves.net>
|
||||
* Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
|
||||
* Copyright (C) 2009-2016 Paul Davis <paul@linuxaudiosystems.com>
|
||||
* Copyright (C) 2014-2019 Robin Gareus <robin@gareus.org>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "ardour/audio_playlist_importer.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "pbd/failed_constructor.h"
|
||||
#include "pbd/compose.h"
|
||||
#include "pbd/error.h"
|
||||
|
||||
#include "ardour/audio_region_importer.h"
|
||||
#include "ardour/session.h"
|
||||
#include "ardour/playlist_factory.h"
|
||||
#include "ardour/session_playlists.h"
|
||||
|
||||
#include "pbd/i18n.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
using namespace ARDOUR;
|
||||
|
||||
/**** Handler ***/
|
||||
AudioPlaylistImportHandler::AudioPlaylistImportHandler (XMLTree const & source, Session & session, AudioRegionImportHandler & region_handler, const char * nodename) :
|
||||
ElementImportHandler (source, session),
|
||||
region_handler (region_handler)
|
||||
{
|
||||
XMLNode const * root = source.root();
|
||||
XMLNode const * playlists;
|
||||
|
||||
if (!(playlists = root->child (nodename))) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
||||
XMLNodeList const & pl_children = playlists->children();
|
||||
for (XMLNodeList::const_iterator it = pl_children.begin(); it != pl_children.end(); ++it) {
|
||||
XMLProperty const * type = (*it)->property("type");
|
||||
if ( !type || type->value() == "audio" ) {
|
||||
try {
|
||||
elements.push_back (ElementPtr ( new AudioPlaylistImporter (source, session, *this, **it)));
|
||||
} catch (failed_constructor const&) {
|
||||
set_dirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
AudioPlaylistImportHandler::get_info () const
|
||||
{
|
||||
return _("Audio Playlists");
|
||||
}
|
||||
|
||||
void
|
||||
AudioPlaylistImportHandler::get_regions (XMLNode const & node, ElementList & list) const
|
||||
{
|
||||
region_handler.create_regions_from_children (node, list);
|
||||
}
|
||||
|
||||
void
|
||||
AudioPlaylistImportHandler::update_region_id (XMLProperty * id_prop)
|
||||
{
|
||||
PBD::ID old_id (id_prop->value());
|
||||
PBD::ID new_id (region_handler.get_new_id (old_id));
|
||||
id_prop->set_value (new_id.to_s());
|
||||
}
|
||||
|
||||
void
|
||||
AudioPlaylistImportHandler::playlists_by_diskstream (PBD::ID const & id, PlaylistList & list) const
|
||||
{
|
||||
for (ElementList::const_iterator it = elements.begin(); it != elements.end(); ++it) {
|
||||
std::shared_ptr<AudioPlaylistImporter> pl = std::dynamic_pointer_cast<AudioPlaylistImporter> (*it);
|
||||
if (pl && pl->orig_diskstream() == id) {
|
||||
list.push_back (PlaylistPtr (new AudioPlaylistImporter (*pl)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*** AudioPlaylistImporter ***/
|
||||
AudioPlaylistImporter::AudioPlaylistImporter (XMLTree const & source, Session & session, AudioPlaylistImportHandler & handler, XMLNode const & node) :
|
||||
ElementImporter (source, session),
|
||||
handler (handler),
|
||||
orig_node (node),
|
||||
xml_playlist (node),
|
||||
diskstream_id ("0")
|
||||
{
|
||||
bool ds_ok = false;
|
||||
|
||||
populate_region_list ();
|
||||
|
||||
// Parse XML
|
||||
XMLPropertyList const & props = xml_playlist.properties();
|
||||
for (XMLPropertyList::const_iterator it = props.begin(); it != props.end(); ++it) {
|
||||
string prop = (*it)->name();
|
||||
if (!prop.compare("type") || !prop.compare("frozen")) {
|
||||
// All ok
|
||||
} else if (!prop.compare("name")) {
|
||||
name = (*it)->value();
|
||||
} else if (!prop.compare("orig-diskstream-id")) {
|
||||
orig_diskstream_id = (*it)->value();
|
||||
ds_ok = true;
|
||||
} else {
|
||||
std::cerr << string_compose (X_("AudioPlaylistImporter did not recognise XML-property \"%1\""), prop) << endmsg;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ds_ok) {
|
||||
error << string_compose (X_("AudioPlaylistImporter (%1): did not find XML-property \"orig_diskstream_id\" which is mandatory"), name) << endmsg;
|
||||
throw failed_constructor();
|
||||
}
|
||||
}
|
||||
|
||||
AudioPlaylistImporter::AudioPlaylistImporter (AudioPlaylistImporter const & other) :
|
||||
ElementImporter (other.source, other.session),
|
||||
handler (other.handler),
|
||||
orig_node (other.orig_node),
|
||||
xml_playlist (other.xml_playlist),
|
||||
orig_diskstream_id (other.orig_diskstream_id)
|
||||
{
|
||||
populate_region_list ();
|
||||
}
|
||||
|
||||
AudioPlaylistImporter::~AudioPlaylistImporter ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
string
|
||||
AudioPlaylistImporter::get_info () const
|
||||
{
|
||||
XMLNodeList children = xml_playlist.children();
|
||||
unsigned int regions = 0;
|
||||
std::ostringstream oss;
|
||||
|
||||
for (XMLNodeIterator it = children.begin(); it != children.end(); it++) {
|
||||
if ((*it)->name() == "Region") {
|
||||
++regions;
|
||||
}
|
||||
}
|
||||
|
||||
oss << regions << " ";
|
||||
|
||||
if (regions == 1) {
|
||||
oss << _("region");
|
||||
} else {
|
||||
oss << _("regions");
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
bool
|
||||
AudioPlaylistImporter::_prepare_move ()
|
||||
{
|
||||
// Rename
|
||||
while (session.playlists()->by_name (name) || !handler.check_name (name)) {
|
||||
std::pair<bool, string> rename_pair = *Rename (_("A playlist with this name already exists, please rename it."), name);
|
||||
if (!rename_pair.first) {
|
||||
return false;
|
||||
}
|
||||
name = rename_pair.second;
|
||||
}
|
||||
|
||||
XMLProperty * p = xml_playlist.property ("name");
|
||||
if (!p) {
|
||||
error << _("badly-formed XML in imported playlist") << endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
p->set_value (name);
|
||||
handler.add_name (name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
AudioPlaylistImporter::_cancel_move ()
|
||||
{
|
||||
handler.remove_name (name);
|
||||
}
|
||||
|
||||
void
|
||||
AudioPlaylistImporter::_move ()
|
||||
{
|
||||
std::shared_ptr<Playlist> playlist;
|
||||
|
||||
// Update diskstream id
|
||||
xml_playlist.property ("orig-diskstream-id")->set_value (diskstream_id.to_s());
|
||||
|
||||
// Update region XML in playlist and prepare sources
|
||||
xml_playlist.remove_nodes("Region");
|
||||
for (RegionList::iterator it = regions.begin(); it != regions.end(); ++it) {
|
||||
xml_playlist.add_child_copy ((*it)->get_xml());
|
||||
(*it)->add_sources_to_session();
|
||||
if ((*it)->broken()) {
|
||||
handler.set_dirty();
|
||||
set_broken();
|
||||
return; // TODO clean up?
|
||||
}
|
||||
}
|
||||
|
||||
// Update region ids in crossfades
|
||||
XMLNodeList crossfades = xml_playlist.children("Crossfade");
|
||||
for (XMLNodeIterator it = crossfades.begin(); it != crossfades.end(); ++it) {
|
||||
XMLProperty * in = (*it)->property("in");
|
||||
XMLProperty * out = (*it)->property("out");
|
||||
if (!in || !out) {
|
||||
error << string_compose (X_("AudioPlaylistImporter (%1): did not find the \"in\" or \"out\" property from a crossfade"), name) << endmsg;
|
||||
continue; // or fatal?
|
||||
}
|
||||
|
||||
handler.update_region_id (in);
|
||||
handler.update_region_id (out);
|
||||
|
||||
// rate convert length and position
|
||||
XMLProperty * length = (*it)->property("length");
|
||||
if (length) {
|
||||
length->set_value (rate_convert_samples (length->value()));
|
||||
}
|
||||
|
||||
XMLProperty * position = (*it)->property("position");
|
||||
if (position) {
|
||||
position->set_value (rate_convert_samples (position->value()));
|
||||
}
|
||||
}
|
||||
|
||||
// Create playlist
|
||||
playlist = PlaylistFactory::create (session, xml_playlist, false);
|
||||
}
|
||||
|
||||
void
|
||||
AudioPlaylistImporter::set_diskstream (PBD::ID const & id)
|
||||
{
|
||||
diskstream_id = id;
|
||||
}
|
||||
|
||||
void
|
||||
AudioPlaylistImporter::populate_region_list ()
|
||||
{
|
||||
ElementImportHandler::ElementList elements;
|
||||
handler.get_regions (orig_node, elements);
|
||||
for (ElementImportHandler::ElementList::iterator it = elements.begin(); it != elements.end(); ++it) {
|
||||
regions.push_back (std::dynamic_pointer_cast<AudioRegionImporter> (*it));
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
UnusedAudioPlaylistImportHandler::get_info () const
|
||||
{
|
||||
return _("Audio Playlists (unused)");
|
||||
}
|
||||
@@ -1,399 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 Sakari Bergen <sakari.bergen@beatwaves.net>
|
||||
* Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
|
||||
* Copyright (C) 2009-2012 David Robillard <d@drobilla.net>
|
||||
* Copyright (C) 2009-2017 Paul Davis <paul@linuxaudiosystems.com>
|
||||
* Copyright (C) 2012 Tim Mayberry <mojofunk@gmail.com>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "ardour/audio_region_importer.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <glibmm/miscutils.h>
|
||||
|
||||
#include "pbd/failed_constructor.h"
|
||||
#include "pbd/compose.h"
|
||||
#include "pbd/error.h"
|
||||
|
||||
#include "ardour/session.h"
|
||||
#include "ardour/region.h"
|
||||
#include "ardour/region_factory.h"
|
||||
#include "ardour/session_directory.h"
|
||||
|
||||
#include "pbd/i18n.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
using namespace ARDOUR;
|
||||
|
||||
/**** Handler ***/
|
||||
AudioRegionImportHandler::AudioRegionImportHandler (XMLTree const & source, Session & session) :
|
||||
ElementImportHandler (source, session)
|
||||
{
|
||||
XMLNode const * root = source.root();
|
||||
XMLNode const * regions;
|
||||
|
||||
if (!(regions = root->child (X_("Regions")))) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
||||
create_regions_from_children (*regions, elements);
|
||||
}
|
||||
|
||||
void
|
||||
AudioRegionImportHandler::create_regions_from_children (XMLNode const & node, ElementList & list)
|
||||
{
|
||||
XMLNodeList const & children = node.children();
|
||||
for (XMLNodeList::const_iterator it = children.begin(); it != children.end(); ++it) {
|
||||
XMLProperty const * type = (*it)->property("type");
|
||||
if (!(*it)->name().compare ("Region") && (!type || type->value() == "audio") ) {
|
||||
try {
|
||||
list.push_back (ElementPtr ( new AudioRegionImporter (source, session, *this, **it)));
|
||||
} catch (failed_constructor const&) {
|
||||
set_dirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
AudioRegionImportHandler::get_info () const
|
||||
{
|
||||
return _("Audio Regions");
|
||||
}
|
||||
|
||||
bool
|
||||
AudioRegionImportHandler::check_source (string const & filename) const
|
||||
{
|
||||
return (sources.find (filename) != sources.end());
|
||||
}
|
||||
|
||||
void
|
||||
AudioRegionImportHandler::add_source (string const & filename, std::shared_ptr<Source> const & source)
|
||||
{
|
||||
sources.insert (SourcePair (filename, source));
|
||||
}
|
||||
|
||||
std::shared_ptr<Source> const &
|
||||
AudioRegionImportHandler::get_source (string const & filename) const
|
||||
{
|
||||
return (sources.find (filename))->second;
|
||||
}
|
||||
|
||||
void
|
||||
AudioRegionImportHandler::register_id (PBD::ID & old_id, PBD::ID & new_id)
|
||||
{
|
||||
id_map.insert (IdPair (old_id, new_id));
|
||||
}
|
||||
|
||||
PBD::ID const &
|
||||
AudioRegionImportHandler::get_new_id (PBD::ID & old_id) const
|
||||
{
|
||||
return (id_map.find (old_id))->second;
|
||||
}
|
||||
|
||||
/*** AudioRegionImporter ***/
|
||||
AudioRegionImporter::AudioRegionImporter (XMLTree const & source, Session & session, AudioRegionImportHandler & handler, XMLNode const & node) :
|
||||
ElementImporter (source, session),
|
||||
xml_region (node),
|
||||
handler (handler),
|
||||
old_id ("0"),
|
||||
region_prepared (false),
|
||||
sources_prepared (false)
|
||||
{
|
||||
if (!parse_xml_region () || !parse_source_xml ()) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
handler.register_id (old_id, id);
|
||||
}
|
||||
|
||||
AudioRegionImporter::~AudioRegionImporter ()
|
||||
{
|
||||
}
|
||||
|
||||
string
|
||||
AudioRegionImporter::get_info () const
|
||||
{
|
||||
samplecnt_t length, position;
|
||||
Timecode::Time length_time, position_time;
|
||||
std::ostringstream oss;
|
||||
|
||||
// Get sample positions
|
||||
std::istringstream iss_length(xml_region.property ("length")->value());
|
||||
iss_length >> length;
|
||||
std::istringstream iss_position(xml_region.property ("position")->value());
|
||||
iss_position >> position;
|
||||
|
||||
// Convert to timecode
|
||||
session.sample_to_timecode(length, length_time, true, false);
|
||||
session.sample_to_timecode(position, position_time, true, false);
|
||||
|
||||
// return info
|
||||
oss << _("Length: ") <<
|
||||
timecode_to_string(length_time) <<
|
||||
_("\nPosition: ") <<
|
||||
timecode_to_string(position_time) <<
|
||||
_("\nChannels: ") <<
|
||||
xml_region.property ("channels")->value();
|
||||
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
bool
|
||||
AudioRegionImporter::_prepare_move ()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
AudioRegionImporter::_cancel_move ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AudioRegionImporter::_move ()
|
||||
{
|
||||
if (!region_prepared) {
|
||||
prepare_region();
|
||||
if (!region_prepared) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (broken()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AudioRegionImporter::parse_xml_region ()
|
||||
{
|
||||
XMLPropertyList const & props = xml_region.properties();
|
||||
bool id_ok = false;
|
||||
bool name_ok = false;
|
||||
|
||||
for (XMLPropertyList::const_iterator it = props.begin(); it != props.end(); ++it) {
|
||||
string prop = (*it)->name();
|
||||
if (!prop.compare ("type") || !prop.compare ("stretch") ||
|
||||
!prop.compare ("shift") || !prop.compare ("first_edit") ||
|
||||
!prop.compare ("layer") || !prop.compare ("flags") ||
|
||||
!prop.compare ("scale-gain") || !prop.compare("channels") ||
|
||||
!prop.compare ("first-edit") ||
|
||||
prop.find ("master-source-") == 0 || prop.find ("source-") == 0) {
|
||||
// All ok
|
||||
} else if (!prop.compare ("start") || !prop.compare ("length") ||
|
||||
!prop.compare ("position") || !prop.compare ("ancestral-start") ||
|
||||
!prop.compare ("ancestral-length") || !prop.compare ("sync-position")) {
|
||||
// Sample rate conversion
|
||||
(*it)->set_value (rate_convert_samples ((*it)->value()));
|
||||
} else if (!prop.compare("id")) {
|
||||
// get old id and update id
|
||||
old_id = (*it)->value();
|
||||
(*it)->set_value (id.to_s());
|
||||
id_ok = true;
|
||||
} else if (!prop.compare("name")) {
|
||||
// rename region if necessary
|
||||
name = (*it)->value();
|
||||
name = RegionFactory::new_region_name (name);
|
||||
(*it)->set_value (name);
|
||||
name_ok = true;
|
||||
} else {
|
||||
std::cerr << string_compose (X_("AudioRegionImporter (%1): did not recognise XML-property \"%2\""), name, prop) << endmsg;
|
||||
}
|
||||
}
|
||||
|
||||
if (!id_ok) {
|
||||
error << string_compose (X_("AudioRegionImporter (%1): did not find necessary XML-property \"id\""), name) << endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!name_ok) {
|
||||
error << X_("AudioRegionImporter: did not find necessary XML-property \"name\"") << endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioRegionImporter::parse_source_xml ()
|
||||
{
|
||||
uint32_t channels;
|
||||
char buf[128];
|
||||
std::string source_dir(get_sound_dir (source));
|
||||
XMLNode * source_node;
|
||||
XMLProperty const * prop;
|
||||
|
||||
// Get XML for sources
|
||||
if (!(source_node = source.root()->child (X_("Sources")))) {
|
||||
return false;
|
||||
}
|
||||
XMLNodeList const & sources = source_node->children();
|
||||
|
||||
// Get source for each channel
|
||||
if (!(prop = xml_region.property ("channels"))) {
|
||||
error << string_compose (X_("AudioRegionImporter (%1): did not find necessary XML-property \"channels\""), name) << endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
channels = atoi (prop->value().c_str());
|
||||
for (uint32_t i = 0; i < channels; ++i) {
|
||||
bool source_found = false;
|
||||
|
||||
// Get id for source-n
|
||||
snprintf (buf, sizeof(buf), X_("source-%d"), i);
|
||||
prop = xml_region.property (buf);
|
||||
if (!prop) {
|
||||
error << string_compose (X_("AudioRegionImporter (%1): did not find necessary XML-property \"%2\""), name, buf) << endmsg;
|
||||
return false;
|
||||
}
|
||||
string source_id = prop->value();
|
||||
|
||||
// Get source
|
||||
for (XMLNodeList::const_iterator it = sources.begin(); it != sources.end(); ++it) {
|
||||
prop = (*it)->property ("id");
|
||||
if (prop && !source_id.compare (prop->value())) {
|
||||
prop = (*it)->property ("name");
|
||||
if (!prop) {
|
||||
error << string_compose (X_("AudioRegionImporter (%1): source %2 has no \"name\" property"), name, source_id) << endmsg;
|
||||
return false;
|
||||
}
|
||||
filenames.push_back (Glib::build_filename (source_dir, prop->value()));
|
||||
source_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!source_found) {
|
||||
error << string_compose (X_("AudioRegionImporter (%1): could not find all necessary sources"), name) << endmsg;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string
|
||||
AudioRegionImporter::get_sound_dir (XMLTree const & tree)
|
||||
{
|
||||
SessionDirectory session_dir(Glib::path_get_dirname (tree.filename()));
|
||||
return session_dir.sound_path();
|
||||
}
|
||||
|
||||
void
|
||||
AudioRegionImporter::prepare_region ()
|
||||
{
|
||||
if (region_prepared) {
|
||||
return;
|
||||
}
|
||||
|
||||
SourceList source_list;
|
||||
prepare_sources();
|
||||
|
||||
// Create source list
|
||||
for (std::list<string>::iterator it = filenames.begin(); it != filenames.end(); ++it) {
|
||||
source_list.push_back (handler.get_source (*it));
|
||||
}
|
||||
|
||||
// create region and update XML
|
||||
std::shared_ptr<Region> r = RegionFactory::create (source_list, xml_region);
|
||||
region.push_back (r);
|
||||
if (*region.begin()) {
|
||||
xml_region = (*region.begin())->get_state();
|
||||
} else {
|
||||
error << string_compose (X_("AudioRegionImporter (%1): could not construct Region"), name) << endmsg;
|
||||
handler.set_errors();
|
||||
}
|
||||
|
||||
region_prepared = true;
|
||||
}
|
||||
|
||||
void
|
||||
AudioRegionImporter::prepare_sources ()
|
||||
{
|
||||
if (sources_prepared) {
|
||||
return;
|
||||
}
|
||||
|
||||
status.total = 0;
|
||||
status.replace_existing_source = false;
|
||||
status.done = false;
|
||||
status.cancel = false;
|
||||
status.freeze = false;
|
||||
status.import_markers = false;
|
||||
status.progress = 0.0;
|
||||
status.quality = SrcBest; // TODO other qualities also
|
||||
status.replace_existing_source = false;
|
||||
status.split_midi_channels = false;
|
||||
status.import_markers = false;
|
||||
|
||||
// Get sources that still need to be imported
|
||||
for (std::list<string>::iterator it = filenames.begin(); it != filenames.end(); ++it) {
|
||||
if (!handler.check_source (*it)) {
|
||||
status.paths.push_back (*it);
|
||||
status.total++;
|
||||
}
|
||||
}
|
||||
|
||||
// import files
|
||||
// TODO: threading & exception handling
|
||||
session.import_files (status);
|
||||
|
||||
// Add imported sources to handlers map
|
||||
std::vector<string>::iterator file_it = status.paths.begin();
|
||||
for (SourceList::iterator source_it = status.sources.begin(); source_it != status.sources.end(); ++source_it) {
|
||||
if (*source_it) {
|
||||
handler.add_source(*file_it, *source_it);
|
||||
} else {
|
||||
error << string_compose (X_("AudioRegionImporter (%1): could not import all necessary sources"), name) << endmsg;
|
||||
handler.set_errors();
|
||||
set_broken();
|
||||
}
|
||||
|
||||
++file_it;
|
||||
}
|
||||
|
||||
sources_prepared = true;
|
||||
}
|
||||
|
||||
void
|
||||
AudioRegionImporter::add_sources_to_session ()
|
||||
{
|
||||
if (!sources_prepared) {
|
||||
prepare_sources();
|
||||
}
|
||||
|
||||
if (broken()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (std::list<string>::iterator it = filenames.begin(); it != filenames.end(); ++it) {
|
||||
session.add_source (handler.get_source (*it));
|
||||
}
|
||||
}
|
||||
|
||||
XMLNode const &
|
||||
AudioRegionImporter::get_xml ()
|
||||
{
|
||||
if(!region_prepared) {
|
||||
prepare_region();
|
||||
}
|
||||
|
||||
return xml_region;
|
||||
}
|
||||
@@ -1,408 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 Sakari Bergen <sakari.bergen@beatwaves.net>
|
||||
* Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
|
||||
* Copyright (C) 2009-2014 David Robillard <d@drobilla.net>
|
||||
* Copyright (C) 2009-2017 Paul Davis <paul@linuxaudiosystems.com>
|
||||
* Copyright (C) 2015-2018 Robin Gareus <robin@gareus.org>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "ardour/audio_track_importer.h"
|
||||
|
||||
#include "ardour/audio_playlist_importer.h"
|
||||
#include "ardour/disk_reader.h"
|
||||
#include "ardour/session.h"
|
||||
|
||||
#include "pbd/controllable.h"
|
||||
#include "pbd/failed_constructor.h"
|
||||
#include "pbd/string_convert.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "pbd/i18n.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
using namespace ARDOUR;
|
||||
|
||||
/*** AudioTrackImportHandler ***/
|
||||
|
||||
AudioTrackImportHandler::AudioTrackImportHandler (XMLTree const & source, Session & session, AudioPlaylistImportHandler & pl_handler) :
|
||||
ElementImportHandler (source, session)
|
||||
{
|
||||
XMLNode const * root = source.root();
|
||||
XMLNode const * routes;
|
||||
|
||||
if (!(routes = root->child ("Routes"))) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
||||
XMLNodeList const & route_list = routes->children();
|
||||
for (XMLNodeList::const_iterator it = route_list.begin(); it != route_list.end(); ++it) {
|
||||
XMLProperty const * type = (*it)->property("default-type");
|
||||
if ( (!type || type->value() == "audio") && ((*it)->property ("diskstream") != 0 || (*it)->property ("diskstream-id") != 0)) {
|
||||
try {
|
||||
elements.push_back (ElementPtr ( new AudioTrackImporter (source, session, *this, **it, pl_handler)));
|
||||
} catch (failed_constructor const&) {
|
||||
set_dirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
AudioTrackImportHandler::get_info () const
|
||||
{
|
||||
return _("Audio Tracks");
|
||||
}
|
||||
|
||||
|
||||
/*** AudioTrackImporter ***/
|
||||
|
||||
AudioTrackImporter::AudioTrackImporter (XMLTree const & source,
|
||||
Session & session,
|
||||
AudioTrackImportHandler & track_handler,
|
||||
XMLNode const & node,
|
||||
AudioPlaylistImportHandler & pl_handler) :
|
||||
ElementImporter (source, session),
|
||||
track_handler (track_handler),
|
||||
xml_track (node),
|
||||
pl_handler (pl_handler)
|
||||
{
|
||||
XMLProperty * prop;
|
||||
|
||||
if (!parse_route_xml ()) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
||||
if (!parse_io ()) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
||||
XMLNodeList const & controllables = node.children (Controllable::xml_node_name);
|
||||
for (XMLNodeList::const_iterator it = controllables.begin(); it != controllables.end(); ++it) {
|
||||
parse_controllable (**it);
|
||||
}
|
||||
|
||||
XMLNode * remote_control = xml_track.child ("RemoteControl");
|
||||
if (remote_control && (prop = remote_control->property ("id"))) {
|
||||
uint32_t control_id = session.ntracks() + session.nbusses() + 1;
|
||||
prop->set_value (to_string (control_id));
|
||||
}
|
||||
|
||||
xml_track.remove_nodes_and_delete ("Extra");
|
||||
}
|
||||
|
||||
AudioTrackImporter::~AudioTrackImporter ()
|
||||
{
|
||||
playlists.clear ();
|
||||
}
|
||||
|
||||
bool
|
||||
AudioTrackImporter::parse_route_xml ()
|
||||
{
|
||||
bool ds_ok = false;
|
||||
|
||||
// Remove order keys, new ones will be generated
|
||||
xml_track.remove_property ("order-keys");
|
||||
|
||||
XMLPropertyList const & props = xml_track.properties();
|
||||
for (XMLPropertyList::const_iterator it = props.begin(); it != props.end(); ++it) {
|
||||
string prop = (*it)->name();
|
||||
if (!prop.compare ("default-type") || !prop.compare ("flags") ||
|
||||
!prop.compare ("active") || !prop.compare ("muted") ||
|
||||
!prop.compare ("soloed") || !prop.compare ("phase-invert") ||
|
||||
!prop.compare ("denormal-protection") || !prop.compare("mute-affects-pre-fader") ||
|
||||
!prop.compare ("mute-affects-post-fader") || !prop.compare("mute-affects-control-outs") ||
|
||||
!prop.compare ("mute-affects-main-outs") || !prop.compare("mode")) {
|
||||
// All ok
|
||||
} else if (!prop.compare("diskstream-id")) {
|
||||
old_ds_id = (*it)->value();
|
||||
(*it)->set_value (new_ds_id.to_s());
|
||||
ds_ok = true;
|
||||
} else {
|
||||
std::cerr << string_compose (X_("AudioTrackImporter: did not recognise XML-property \"%1\""), prop) << endmsg;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ds_ok) {
|
||||
error << X_("AudioTrackImporter: did not find necessary XML-property \"diskstream-id\"") << endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioTrackImporter::parse_io ()
|
||||
{
|
||||
XMLNode * io;
|
||||
bool name_ok = false;
|
||||
bool id_ok = false;
|
||||
|
||||
if (!(io = xml_track.child ("IO"))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
XMLPropertyList const & props = io->properties();
|
||||
|
||||
for (XMLPropertyList::const_iterator it = props.begin(); it != props.end(); ++it) {
|
||||
string prop = (*it)->name();
|
||||
if (!prop.compare ("gain") || !prop.compare ("iolimits")) {
|
||||
// All ok
|
||||
} else if (!prop.compare("name")) {
|
||||
name = (*it)->value();
|
||||
name_ok = true;
|
||||
} else if (!prop.compare("id")) {
|
||||
PBD::ID id;
|
||||
(*it)->set_value (id.to_s());
|
||||
id_ok = true;
|
||||
} else if (!prop.compare("inputs")) {
|
||||
// TODO Handle this properly!
|
||||
/* Input and output ports are counted and added empty, so that no in/output connecting function fails. */
|
||||
uint32_t num_inputs = std::count ((*it)->value().begin(), (*it)->value().end(), '{');
|
||||
std::string value;
|
||||
for (uint32_t i = 0; i < num_inputs; i++) { value += "{}"; }
|
||||
(*it)->set_value (value);
|
||||
} else if (!prop.compare("outputs")) {
|
||||
// TODO See comments above
|
||||
uint32_t num_outputs = std::count ((*it)->value().begin(), (*it)->value().end(), '{');
|
||||
std::string value;
|
||||
for (uint32_t i = 0; i < num_outputs; i++) { value += "{}"; }
|
||||
(*it)->set_value (value);
|
||||
} else {
|
||||
std::cerr << string_compose (X_("AudioTrackImporter: did not recognise XML-property \"%1\""), prop) << endmsg;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name_ok) {
|
||||
error << X_("AudioTrackImporter: did not find necessary XML-property \"name\"") << endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!id_ok) {
|
||||
error << X_("AudioTrackImporter: did not find necessary XML-property \"id\"") << endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
XMLNodeList const & controllables = io->children (Controllable::xml_node_name);
|
||||
for (XMLNodeList::const_iterator it = controllables.begin(); it != controllables.end(); ++it) {
|
||||
parse_controllable (**it);
|
||||
}
|
||||
|
||||
XMLNodeList const & processors = io->children ("Processor");
|
||||
for (XMLNodeList::const_iterator it = processors.begin(); it != processors.end(); ++it) {
|
||||
parse_processor (**it);
|
||||
}
|
||||
|
||||
XMLNodeList const & automations = io->children ("Automation");
|
||||
for (XMLNodeList::const_iterator it = automations.begin(); it != automations.end(); ++it) {
|
||||
parse_automation (**it);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
string
|
||||
AudioTrackImporter::get_info () const
|
||||
{
|
||||
// TODO
|
||||
return name;
|
||||
}
|
||||
|
||||
/** @return true if everything is ok */
|
||||
bool
|
||||
AudioTrackImporter::_prepare_move ()
|
||||
{
|
||||
/* Copy dependent playlists */
|
||||
|
||||
pl_handler.playlists_by_diskstream (old_ds_id, playlists);
|
||||
|
||||
for (PlaylistList::iterator it = playlists.begin(); it != playlists.end(); ++it) {
|
||||
if (!(*it)->prepare_move ()) {
|
||||
playlists.clear ();
|
||||
return false;
|
||||
}
|
||||
(*it)->set_diskstream (new_ds_id);
|
||||
}
|
||||
|
||||
/* Rename */
|
||||
|
||||
while (session.route_by_name (name) || !track_handler.check_name (name)) {
|
||||
std::pair<bool, string> rename_pair = *Rename (_("A playlist with this name already exists, please rename it."), name);
|
||||
if (!rename_pair.first) {
|
||||
return false;
|
||||
}
|
||||
name = rename_pair.second;
|
||||
}
|
||||
|
||||
XMLNode* c = xml_track.child ("IO");
|
||||
if (!c) {
|
||||
error << _("badly-formed XML in imported track") << endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
XMLProperty * p = c->property ("name");
|
||||
if (!p) {
|
||||
error << _("badly-formed XML in imported track") << endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
p->set_value (name);
|
||||
|
||||
track_handler.add_name (name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
AudioTrackImporter::_cancel_move ()
|
||||
{
|
||||
track_handler.remove_name (name);
|
||||
playlists.clear ();
|
||||
}
|
||||
|
||||
void
|
||||
AudioTrackImporter::_move ()
|
||||
{
|
||||
/* XXX DISK */
|
||||
#if 0
|
||||
/* Add diskstream */
|
||||
|
||||
std::shared_ptr<XMLSharedNodeList> ds_node_list;
|
||||
string xpath = "/Session/DiskStreams/AudioDiskstream[@id='" + old_ds_id.to_s() + "']";
|
||||
ds_node_list = source.find (xpath);
|
||||
|
||||
if (ds_node_list->size() != 1) {
|
||||
error << string_compose (_("Error Importing Audio track %1"), name) << endmsg;
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<XMLNode> ds_node = ds_node_list->front();
|
||||
XMLProperty * p = ds_node->property (X_("id"));
|
||||
assert (p);
|
||||
p->set_value (new_ds_id.to_s());
|
||||
|
||||
std::shared_ptr<DiskReader> new_ds (new DiskReader (session, *ds_node));
|
||||
new_ds->set_name (name);
|
||||
new_ds->do_refill_with_alloc (true, false);
|
||||
new_ds->set_block_size (session.get_block_size ());
|
||||
|
||||
/* Import playlists */
|
||||
|
||||
for (PlaylistList::const_iterator it = playlists.begin(); it != playlists.end(); ++it) {
|
||||
(*it)->move ();
|
||||
}
|
||||
|
||||
/* Import track */
|
||||
|
||||
XMLNode routes ("Routes");
|
||||
routes.add_child_copy (xml_track);
|
||||
session.load_routes (routes, 3000);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
AudioTrackImporter::parse_processor (XMLNode & node)
|
||||
{
|
||||
XMLNode * automation = node.child ("Automation");
|
||||
if (automation) {
|
||||
parse_automation (*automation);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioTrackImporter::parse_controllable (XMLNode & node)
|
||||
{
|
||||
XMLProperty * prop;
|
||||
|
||||
if ((prop = node.property ("id"))) {
|
||||
PBD::ID new_id;
|
||||
prop->set_value (new_id.to_s());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioTrackImporter::parse_automation (XMLNode & node)
|
||||
{
|
||||
|
||||
XMLNodeList const & lists = node.children ("AutomationList");
|
||||
for (XMLNodeList::const_iterator it = lists.begin(); it != lists.end(); ++it) {
|
||||
XMLProperty * prop;
|
||||
|
||||
if ((prop = (*it)->property ("id"))) {
|
||||
PBD::ID id;
|
||||
prop->set_value (id.to_s());
|
||||
}
|
||||
|
||||
if (!(*it)->name().compare ("events")) {
|
||||
rate_convert_events (**it);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AudioTrackImporter::rate_convert_events (XMLNode & node)
|
||||
{
|
||||
if (node.children().empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
XMLNode* content_node = node.children().front();
|
||||
|
||||
if (content_node->content().empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::stringstream str (content_node->content());
|
||||
std::ostringstream new_content;
|
||||
|
||||
samplecnt_t x;
|
||||
double y;
|
||||
bool ok = true;
|
||||
|
||||
while (str) {
|
||||
str >> x;
|
||||
if (!str) {
|
||||
break;
|
||||
}
|
||||
str >> y;
|
||||
if (!str) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
new_content << rate_convert_samples (x) << ' ' << y;
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
error << X_("AudioTrackImporter: error in rate converting automation events") << endmsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
content_node->set_content (new_content.str());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Sakari Bergen <sakari.bergen@beatwaves.net>
|
||||
* Copyright (C) 2009-2010 Carl Hetherington <carl@carlh.net>
|
||||
* Copyright (C) 2009-2017 Paul Davis <paul@linuxaudiosystems.com>
|
||||
* Copyright (C) 2009 David Robillard <d@drobilla.net>
|
||||
* Copyright (C) 2016 Tim Mayberry <mojofunk@gmail.com>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "ardour/element_importer.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "pbd/string_convert.h"
|
||||
#include "ardour/session.h"
|
||||
|
||||
#include "pbd/i18n.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
using namespace ARDOUR;
|
||||
|
||||
PBD::Signal<std::pair<bool, string>(string, string)> ElementImporter::Rename;
|
||||
PBD::Signal<bool(string)> ElementImporter::Prompt;
|
||||
|
||||
ElementImporter::ElementImporter (XMLTree const & source, ARDOUR::Session & session) :
|
||||
source (source),
|
||||
session(session),
|
||||
_queued (false),
|
||||
_broken (false)
|
||||
{
|
||||
source.root()->get_property ("sample-rate", sample_rate);
|
||||
}
|
||||
|
||||
ElementImporter::~ElementImporter ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ElementImporter::move ()
|
||||
{
|
||||
if (!_queued) { return; }
|
||||
_move ();
|
||||
}
|
||||
|
||||
bool
|
||||
ElementImporter::prepare_move ()
|
||||
{
|
||||
if (_queued) {
|
||||
return true;
|
||||
}
|
||||
_queued = _prepare_move ();
|
||||
return _queued;
|
||||
}
|
||||
|
||||
void
|
||||
ElementImporter::cancel_move ()
|
||||
{
|
||||
if (!_queued) { return; }
|
||||
_cancel_move ();
|
||||
}
|
||||
|
||||
string
|
||||
ElementImporter::timecode_to_string(Timecode::Time & time) const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << std::setfill('0') << std::right <<
|
||||
std::setw(2) <<
|
||||
time.hours << ":" <<
|
||||
std::setw(2) <<
|
||||
time.minutes << ":" <<
|
||||
std::setw(2) <<
|
||||
time.seconds << ":" <<
|
||||
std::setw(2) <<
|
||||
time.frames;
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
samplecnt_t
|
||||
ElementImporter::rate_convert_samples (samplecnt_t samples) const
|
||||
{
|
||||
if (sample_rate == session.sample_rate()) {
|
||||
return samples;
|
||||
}
|
||||
|
||||
// +0.5 for proper rounding
|
||||
return static_cast<samplecnt_t> (samples * (static_cast<double> (session.nominal_sample_rate()) / sample_rate) + 0.5);
|
||||
}
|
||||
|
||||
string
|
||||
ElementImporter::rate_convert_samples (string const & samples) const
|
||||
{
|
||||
return to_string (rate_convert_samples (string_to<uint32_t>(samples)));
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2010 Carl Hetherington <carl@carlh.net>
|
||||
* Copyright (C) 2008 Sakari Bergen <sakari.bergen@beatwaves.net>
|
||||
* Copyright (C) 2009-2010 David Robillard <d@drobilla.net>
|
||||
* Copyright (C) 2009-2017 Paul Davis <paul@linuxaudiosystems.com>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "ardour/location_importer.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "ardour/session.h"
|
||||
#include "pbd/convert.h"
|
||||
#include "pbd/failed_constructor.h"
|
||||
|
||||
#include "pbd/i18n.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
using namespace ARDOUR;
|
||||
|
||||
/**** Handler ***/
|
||||
LocationImportHandler::LocationImportHandler (XMLTree const & source, Session & session) :
|
||||
ElementImportHandler (source, session)
|
||||
{
|
||||
XMLNode const *root = source.root();
|
||||
XMLNode const * location_node;
|
||||
|
||||
if (!(location_node = root->child ("Locations"))) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
||||
// Construct importable locations
|
||||
XMLNodeList const & locations = location_node->children();
|
||||
for (XMLNodeList::const_iterator it = locations.begin(); it != locations.end(); ++it) {
|
||||
try {
|
||||
elements.push_back (ElementPtr ( new LocationImporter (source, session, *this, **it)));
|
||||
} catch (failed_constructor const&) {
|
||||
_dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
LocationImportHandler::get_info () const
|
||||
{
|
||||
return _("Locations");
|
||||
}
|
||||
|
||||
/*** LocationImporter ***/
|
||||
LocationImporter::LocationImporter (XMLTree const & source, Session & session, LocationImportHandler & handler, XMLNode const & node) :
|
||||
ElementImporter (source, session),
|
||||
handler (handler),
|
||||
xml_location (node),
|
||||
location (0)
|
||||
{
|
||||
// Parse XML
|
||||
bool name_ok = false;
|
||||
XMLPropertyList props = xml_location.properties();
|
||||
|
||||
for (XMLPropertyIterator it = props.begin(); it != props.end(); ++it) {
|
||||
string prop = (*it)->name();
|
||||
if (!prop.compare ("id") || !prop.compare ("flags") || !prop.compare ("locked")) {
|
||||
// All ok
|
||||
} else if (!prop.compare ("start") || !prop.compare ("end")) {
|
||||
// Sample rate conversion
|
||||
(*it)->set_value (rate_convert_samples ((*it)->value()));
|
||||
} else if (!prop.compare ("name")) {
|
||||
// rename region if necessary
|
||||
name = (*it)->value();
|
||||
name_ok = true;
|
||||
} else {
|
||||
std::cerr << string_compose (X_("LocationImporter did not recognise XML-property \"%1\""), prop) << endmsg;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name_ok) {
|
||||
error << X_("LocationImporter did not find necessary XML-property \"name\"") << endmsg;
|
||||
throw failed_constructor();
|
||||
}
|
||||
}
|
||||
|
||||
LocationImporter::~LocationImporter ()
|
||||
{
|
||||
if (!queued()) {
|
||||
delete location;
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
LocationImporter::get_info () const
|
||||
{
|
||||
samplepos_t start, end;
|
||||
Timecode::Time start_time, end_time;
|
||||
|
||||
// Get sample positions
|
||||
std::istringstream iss_start (xml_location.property ("start")->value());
|
||||
iss_start >> start;
|
||||
std::istringstream iss_end (xml_location.property ("end")->value());
|
||||
iss_end >> end;
|
||||
|
||||
// Convert to timecode
|
||||
session.sample_to_timecode (start, start_time, true, false);
|
||||
session.sample_to_timecode (end, end_time, true, false);
|
||||
|
||||
// return info
|
||||
std::ostringstream oss;
|
||||
if (start == end) {
|
||||
oss << _("Location: ") << timecode_to_string (start_time);
|
||||
} else {
|
||||
oss << _("Range\nstart: ") << timecode_to_string (start_time) <<
|
||||
_("\nend: ") << timecode_to_string (end_time);
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
bool
|
||||
LocationImporter::_prepare_move ()
|
||||
{
|
||||
try {
|
||||
Location const original (session, xml_location);
|
||||
location = new Location (original, false); // Updates id
|
||||
} catch (failed_constructor& err) {
|
||||
throw std::runtime_error (X_("Error in session file!"));
|
||||
return false;
|
||||
}
|
||||
|
||||
std::pair<bool, string> rename_pair;
|
||||
|
||||
if (location->is_auto_punch()) {
|
||||
rename_pair = *Rename (_("The location is the Punch range. It will be imported as a normal range.\nYou may rename the imported location:"), name);
|
||||
if (!rename_pair.first) {
|
||||
return false;
|
||||
}
|
||||
|
||||
name = rename_pair.second;
|
||||
location->set_auto_punch (false, this);
|
||||
location->set_is_range_marker (true, this);
|
||||
}
|
||||
|
||||
if (location->is_auto_loop()) {
|
||||
rename_pair = *Rename (_("The location is a Loop range. It will be imported as a normal range.\nYou may rename the imported location:"), name);
|
||||
if (!rename_pair.first) { return false; }
|
||||
|
||||
location->set_auto_loop (false, this);
|
||||
location->set_is_range_marker (true, this);
|
||||
}
|
||||
|
||||
// duplicate name checking
|
||||
Locations::LocationList const & locations(session.locations()->list());
|
||||
for (Locations::LocationList::const_iterator it = locations.begin(); it != locations.end(); ++it) {
|
||||
if (!((*it)->name().compare (location->name())) || !handler.check_name (location->name())) {
|
||||
rename_pair = *Rename (_("A location with that name already exists.\nYou may rename the imported location:"), name);
|
||||
if (!rename_pair.first) { return false; }
|
||||
name = rename_pair.second;
|
||||
}
|
||||
}
|
||||
|
||||
location->set_name (name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
LocationImporter::_cancel_move ()
|
||||
{
|
||||
delete location;
|
||||
location = 0;
|
||||
}
|
||||
|
||||
void
|
||||
LocationImporter::_move ()
|
||||
{
|
||||
session.locations()->add (location);
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Sakari Bergen <sakari.bergen@beatwaves.net>
|
||||
* Copyright (C) 2009-2012 David Robillard <d@drobilla.net>
|
||||
* Copyright (C) 2009-2016 Paul Davis <paul@linuxaudiosystems.com>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "ardour/tempo_map_importer.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "ardour/session.h"
|
||||
#include "ardour/tempo.h"
|
||||
#include "pbd/failed_constructor.h"
|
||||
|
||||
#include "pbd/i18n.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace PBD;
|
||||
using namespace ARDOUR;
|
||||
using namespace Temporal;
|
||||
|
||||
/**** Handler ***/
|
||||
TempoMapImportHandler::TempoMapImportHandler (XMLTree const & source, Session & session) :
|
||||
ElementImportHandler (source, session)
|
||||
{
|
||||
XMLNode const * root = source.root();
|
||||
XMLNode const * tempo_map;
|
||||
|
||||
if (!(tempo_map = root->child (X_("TempoMap")))) {
|
||||
throw failed_constructor();
|
||||
}
|
||||
|
||||
elements.push_back (ElementPtr ( new TempoMapImporter (source, session, *tempo_map)));
|
||||
}
|
||||
|
||||
string
|
||||
TempoMapImportHandler::get_info () const
|
||||
{
|
||||
return _("Tempo map");
|
||||
}
|
||||
|
||||
/*** TempoMapImporter ***/
|
||||
TempoMapImporter::TempoMapImporter (XMLTree const & source, Session & session, XMLNode const & node) :
|
||||
ElementImporter (source, session),
|
||||
xml_tempo_map (node)
|
||||
{
|
||||
name = _("Tempo Map");
|
||||
}
|
||||
|
||||
string
|
||||
TempoMapImporter::get_info () const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
unsigned int tempos = 0;
|
||||
unsigned int meters = 0;
|
||||
XMLNodeList children = xml_tempo_map.children();
|
||||
|
||||
for (XMLNodeIterator it = children.begin(); it != children.end(); it++) {
|
||||
if ((*it)->name() == "Tempo") {
|
||||
tempos++;
|
||||
} else if ((*it)->name() == "Meters") {
|
||||
meters++;
|
||||
}
|
||||
}
|
||||
|
||||
// return info
|
||||
oss << _("Tempo marks: ") << tempos << _("\nMeter marks: ") << meters;
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
bool
|
||||
TempoMapImporter::_prepare_move ()
|
||||
{
|
||||
// Prompt user for verification
|
||||
std::optional<bool> replace = Prompt (_("This will replace the current tempo map!\nAre you sure you want to do this?"));
|
||||
return replace.value_or (false);
|
||||
}
|
||||
|
||||
void
|
||||
TempoMapImporter::_cancel_move ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
TempoMapImporter::_move ()
|
||||
{
|
||||
TempoMap::WritableSharedPtr tmap (TempoMap::write_copy());
|
||||
tmap->set_state (xml_tempo_map, Stateful::current_state_version);
|
||||
TempoMap::update (tmap);
|
||||
}
|
||||
@@ -20,12 +20,9 @@ libardour_sources = [
|
||||
'audio_buffer.cc',
|
||||
'audio_library.cc',
|
||||
'audio_playlist.cc',
|
||||
'audio_playlist_importer.cc',
|
||||
'audio_playlist_source.cc',
|
||||
'audio_port.cc',
|
||||
'audio_region_importer.cc',
|
||||
'audio_track.cc',
|
||||
'audio_track_importer.cc',
|
||||
'audioanalyser.cc',
|
||||
'audioengine.cc',
|
||||
'audiofile_tagger.cc',
|
||||
@@ -67,7 +64,6 @@ libardour_sources = [
|
||||
'dsp_filter.cc',
|
||||
'ebur128_analysis.cc',
|
||||
'element_import_handler.cc',
|
||||
'element_importer.cc',
|
||||
'engine_slave.cc',
|
||||
'enums.cc',
|
||||
'event_type_map.cc',
|
||||
@@ -117,7 +113,6 @@ libardour_sources = [
|
||||
'legatize.cc',
|
||||
'library.cc',
|
||||
'location.cc',
|
||||
'location_importer.cc',
|
||||
'ltc_file_reader.cc',
|
||||
'ltc_slave.cc',
|
||||
'lua_api.cc',
|
||||
@@ -261,7 +256,6 @@ libardour_sources = [
|
||||
'rt_midibuffer.cc',
|
||||
'tailtime.cc',
|
||||
'template_utils.cc',
|
||||
'tempo_map_importer.cc',
|
||||
'thawlist.cc',
|
||||
'thread_buffers.cc',
|
||||
'ticker.cc',
|
||||
|
||||
Reference in New Issue
Block a user