~ubuntu-branches/ubuntu/utopic/ardour3/utopic

« back to all changes in this revision

Viewing changes to libs/ardour/audio_playlist_importer.cc

  • Committer: Package Import Robot
  • Author(s): Felipe Sateler
  • Date: 2013-09-21 19:05:02 UTC
  • Revision ID: package-import@ubuntu.com-20130921190502-8gsftrku6jnzhd7v
Tags: upstream-3.4~dfsg
ImportĀ upstreamĀ versionĀ 3.4~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright (C) 2008 Paul Davis
 
3
    Author: Sakari Bergen
 
4
 
 
5
    This program is free software; you can redistribute it and/or modify
 
6
    it under the terms of the GNU General Public License as published by
 
7
    the Free Software Foundation; either version 2 of the License, or
 
8
    (at your option) any later version.
 
9
 
 
10
    This program is distributed in the hope that it will be useful,
 
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
    GNU General Public License for more details.
 
14
 
 
15
    You should have received a copy of the GNU General Public License
 
16
    along with this program; if not, write to the Free Software
 
17
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
18
 
 
19
*/
 
20
 
 
21
#include "ardour/audio_playlist_importer.h"
 
22
 
 
23
#include <sstream>
 
24
 
 
25
#include "pbd/failed_constructor.h"
 
26
#include "pbd/compose.h"
 
27
#include "pbd/error.h"
 
28
 
 
29
#include "ardour/audio_region_importer.h"
 
30
#include "ardour/session.h"
 
31
#include "ardour/playlist_factory.h"
 
32
#include "ardour/session_playlists.h"
 
33
 
 
34
#include "i18n.h"
 
35
 
 
36
using namespace std;
 
37
using namespace PBD;
 
38
using namespace ARDOUR;
 
39
 
 
40
/**** Handler ***/
 
41
AudioPlaylistImportHandler::AudioPlaylistImportHandler (XMLTree const & source, Session & session, AudioRegionImportHandler & region_handler, const char * nodename) :
 
42
  ElementImportHandler (source, session),
 
43
  region_handler (region_handler)
 
44
{
 
45
        XMLNode const * root = source.root();
 
46
        XMLNode const * playlists;
 
47
 
 
48
        if (!(playlists = root->child (nodename))) {
 
49
                throw failed_constructor();
 
50
        }
 
51
 
 
52
        XMLNodeList const & pl_children = playlists->children();
 
53
        for (XMLNodeList::const_iterator it = pl_children.begin(); it != pl_children.end(); ++it) {
 
54
                const XMLProperty* type = (*it)->property("type");
 
55
                if ( !type || type->value() == "audio" ) {
 
56
                        try {
 
57
                                elements.push_back (ElementPtr ( new AudioPlaylistImporter (source, session, *this, **it)));
 
58
                        } catch (failed_constructor err) {
 
59
                                set_dirty();
 
60
                        }
 
61
                }
 
62
        }
 
63
}
 
64
 
 
65
string
 
66
AudioPlaylistImportHandler::get_info () const
 
67
{
 
68
        return _("Audio Playlists");
 
69
}
 
70
 
 
71
void
 
72
AudioPlaylistImportHandler::get_regions (XMLNode const & node, ElementList & list) const
 
73
{
 
74
        region_handler.create_regions_from_children (node, list);
 
75
}
 
76
 
 
77
void
 
78
AudioPlaylistImportHandler::update_region_id (XMLProperty* id_prop)
 
79
{
 
80
        PBD::ID old_id (id_prop->value());
 
81
        PBD::ID new_id (region_handler.get_new_id (old_id));
 
82
        id_prop->set_value (new_id.to_s());
 
83
}
 
84
 
 
85
void
 
86
AudioPlaylistImportHandler::playlists_by_diskstream (PBD::ID const & id, PlaylistList & list) const
 
87
{
 
88
        for (ElementList::const_iterator it = elements.begin(); it != elements.end(); ++it) {
 
89
                boost::shared_ptr<AudioPlaylistImporter> pl = boost::dynamic_pointer_cast<AudioPlaylistImporter> (*it);
 
90
                if (pl && pl->orig_diskstream() == id) {
 
91
                        list.push_back (PlaylistPtr (new AudioPlaylistImporter (*pl)));
 
92
                }
 
93
        }
 
94
}
 
95
 
 
96
/*** AudioPlaylistImporter ***/
 
97
AudioPlaylistImporter::AudioPlaylistImporter (XMLTree const & source, Session & session, AudioPlaylistImportHandler & handler, XMLNode const & node) :
 
98
  ElementImporter (source, session),
 
99
  handler (handler),
 
100
  orig_node (node),
 
101
  xml_playlist (node),
 
102
  diskstream_id ("0")
 
103
{
 
104
        bool ds_ok = false;
 
105
 
 
106
        populate_region_list ();
 
107
 
 
108
        // Parse XML
 
109
        XMLPropertyList const & props = xml_playlist.properties();
 
110
        for (XMLPropertyList::const_iterator it = props.begin(); it != props.end(); ++it) {
 
111
                string prop = (*it)->name();
 
112
                if (!prop.compare("type") || !prop.compare("frozen")) {
 
113
                        // All ok
 
114
                } else if (!prop.compare("name")) {
 
115
                        name = (*it)->value();
 
116
                } else if (!prop.compare("orig-diskstream-id")) {
 
117
                        orig_diskstream_id = (*it)->value();
 
118
                        ds_ok = true;
 
119
                } else {
 
120
                        std::cerr << string_compose (X_("AudioPlaylistImporter did not recognise XML-property \"%1\""), prop) << endmsg;
 
121
                }
 
122
        }
 
123
 
 
124
        if (!ds_ok) {
 
125
                error << string_compose (X_("AudioPlaylistImporter (%1): did not find XML-property \"orig_diskstream_id\" which is mandatory"), name) << endmsg;
 
126
                throw failed_constructor();
 
127
        }
 
128
}
 
129
 
 
130
AudioPlaylistImporter::AudioPlaylistImporter (AudioPlaylistImporter const & other) :
 
131
  ElementImporter (other.source, other.session),
 
132
  handler (other.handler),
 
133
  orig_node (other.orig_node),
 
134
  xml_playlist (other.xml_playlist),
 
135
  orig_diskstream_id (other.orig_diskstream_id)
 
136
{
 
137
        populate_region_list ();
 
138
}
 
139
 
 
140
AudioPlaylistImporter::~AudioPlaylistImporter ()
 
141
{
 
142
 
 
143
}
 
144
 
 
145
string
 
146
AudioPlaylistImporter::get_info () const
 
147
{
 
148
        XMLNodeList children = xml_playlist.children();
 
149
        unsigned int regions = 0;
 
150
        std::ostringstream oss;
 
151
 
 
152
        for (XMLNodeIterator it = children.begin(); it != children.end(); it++) {
 
153
                if ((*it)->name() == "Region") {
 
154
                        ++regions;
 
155
                }
 
156
        }
 
157
 
 
158
        oss << regions << " ";
 
159
 
 
160
        if (regions == 1) {
 
161
                oss << _("region");
 
162
        } else {
 
163
                oss << _("regions");
 
164
        }
 
165
 
 
166
        return oss.str();
 
167
}
 
168
 
 
169
bool
 
170
AudioPlaylistImporter::_prepare_move ()
 
171
{
 
172
        // Rename
 
173
        while (session.playlists->by_name (name) || !handler.check_name (name)) {
 
174
                std::pair<bool, string> rename_pair = *Rename (_("A playlist with this name already exists, please rename it."), name);
 
175
                if (!rename_pair.first) {
 
176
                        return false;
 
177
                }
 
178
                name = rename_pair.second;
 
179
        }
 
180
        
 
181
        XMLProperty* p = xml_playlist.property ("name");
 
182
        if (!p) {
 
183
                error << _("badly-formed XML in imported playlist") << endmsg;
 
184
        }
 
185
 
 
186
        p->set_value (name);
 
187
        handler.add_name (name);
 
188
 
 
189
        return true;
 
190
}
 
191
 
 
192
void
 
193
AudioPlaylistImporter::_cancel_move ()
 
194
{
 
195
        handler.remove_name (name);
 
196
}
 
197
 
 
198
void
 
199
AudioPlaylistImporter::_move ()
 
200
{
 
201
        boost::shared_ptr<Playlist> playlist;
 
202
 
 
203
        // Update diskstream id
 
204
        xml_playlist.property ("orig-diskstream-id")->set_value (diskstream_id.to_s());
 
205
 
 
206
        // Update region XML in playlist and prepare sources
 
207
        xml_playlist.remove_nodes("Region");
 
208
        for (RegionList::iterator it = regions.begin(); it != regions.end(); ++it) {
 
209
                xml_playlist.add_child_copy ((*it)->get_xml());
 
210
                (*it)->add_sources_to_session();
 
211
                if ((*it)->broken()) {
 
212
                        handler.set_dirty();
 
213
                        set_broken();
 
214
                        return; // TODO clean up?
 
215
                }
 
216
        }
 
217
 
 
218
        // Update region ids in crossfades
 
219
        XMLNodeList crossfades = xml_playlist.children("Crossfade");
 
220
        for (XMLNodeIterator it = crossfades.begin(); it != crossfades.end(); ++it) {
 
221
                XMLProperty* in = (*it)->property("in");
 
222
                XMLProperty* out = (*it)->property("out");
 
223
                if (!in || !out) {
 
224
                        error << string_compose (X_("AudioPlaylistImporter (%1): did not find the \"in\" or \"out\" property from a crossfade"), name) << endmsg;
 
225
                }
 
226
 
 
227
                handler.update_region_id (in);
 
228
                handler.update_region_id (out);
 
229
 
 
230
                // rate convert length and position
 
231
                XMLProperty* length = (*it)->property("length");
 
232
                if (length) {
 
233
                        length->set_value (rate_convert_samples (length->value()));
 
234
                }
 
235
 
 
236
                XMLProperty* position = (*it)->property("position");
 
237
                if (position) {
 
238
                        position->set_value (rate_convert_samples (position->value()));
 
239
                }
 
240
        }
 
241
 
 
242
        // Create playlist
 
243
        playlist = PlaylistFactory::create (session, xml_playlist, false, true);
 
244
}
 
245
 
 
246
void
 
247
AudioPlaylistImporter::set_diskstream (PBD::ID const & id)
 
248
{
 
249
        diskstream_id = id;
 
250
}
 
251
 
 
252
void
 
253
AudioPlaylistImporter::populate_region_list ()
 
254
{
 
255
        ElementImportHandler::ElementList elements;
 
256
        handler.get_regions (orig_node, elements);
 
257
        for (ElementImportHandler::ElementList::iterator it = elements.begin(); it != elements.end(); ++it) {
 
258
                regions.push_back (boost::dynamic_pointer_cast<AudioRegionImporter> (*it));
 
259
        }
 
260
}
 
261
 
 
262
string
 
263
UnusedAudioPlaylistImportHandler::get_info () const
 
264
{
 
265
        return _("Audio Playlists (unused)");
 
266
}