Merged with trunk R1141
[ardour.git] / libs / ardour / source_factory.cc
1 /*
2     Copyright (C) 2000-2006 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18     $Id$
19 */
20
21 #include <pbd/error.h>
22
23 #include <ardour/source_factory.h>
24 #include <ardour/sndfilesource.h>
25 #include <ardour/smf_source.h>
26 #include <ardour/destructive_filesource.h>
27 #include <ardour/configuration.h>
28
29 #ifdef HAVE_COREAUDIO
30 #include <ardour/coreaudiosource.h>
31 #endif
32
33 #include "i18n.h"
34
35 using namespace ARDOUR;
36 using namespace std;
37 using namespace PBD;
38
39 sigc::signal<void,boost::shared_ptr<Source> > SourceFactory::SourceCreated;
40
41 int
42 SourceFactory::setup_peakfile (boost::shared_ptr<Source> s)
43 {
44         boost::shared_ptr<AudioSource> as (boost::dynamic_pointer_cast<AudioSource> (s));
45         if (as) {
46                 if (as->setup_peakfile ()) {
47                         error << string_compose("SourceFactory: could not set up peakfile for %1", as->name()) << endmsg;
48                         return -1;
49                 }
50         }
51
52         return 0;
53 }
54
55 #ifdef HAVE_COREAUDIO
56 boost::shared_ptr<Source>
57 SourceFactory::create (Session& s, const XMLNode& node)
58 {
59         DataType type = DataType::AUDIO;
60         const XMLProperty* prop = node.property("type");
61         if (prop) {
62                 type = DataType(prop->value());
63         }
64
65         if (type == DataType::AUDIO) {
66
67                 if (node.property (X_("destructive")) != 0) {
68
69                         boost::shared_ptr<Source> ret (new DestructiveFileSource (s, node));
70                         if (setup_peakfile (ret)) {
71                                 return boost::shared_ptr<Source>();
72                         }
73                         SourceCreated (ret);
74                         return ret;
75
76                 } else {
77                 
78                 try {
79                         boost::shared_ptr<Source> ret (new CoreAudioSource (s, node));
80                         if (setup_peakfile (ret)) {
81                                 return boost::shared_ptr<Source>();
82                         }
83                         SourceCreated (ret);
84                         return ret;
85                 
86                 } catch (failed_constructor& err) {
87
88                         try {
89                                 boost::shared_ptr<Source> ret (new CoreAudioSource (node));
90                                 SourceCreated (ret);
91                                 return ret;
92                         } 
93
94
95                         catch (failed_constructor& err) {
96
97                                 boost::shared_ptr<Source> ret (new SndFileSource (s, node));
98                                 if (setup_peakfile (ret)) {
99                                         return boost::shared_ptr<Source>();
100                                 }
101                                 SourceCreated (ret);
102                                 return ret;
103                         }
104                 }
105
106         } else if (type == DataType::MIDI) {
107                 
108                 boost::shared_ptr<Source> ret (new SMFSource (node));
109                 SourceCreated (ret);
110                 return ret;
111
112         }
113
114         return boost::shared_ptr<Source>();
115 }
116
117 #else
118
119 boost::shared_ptr<Source>
120 SourceFactory::create (Session& s, const XMLNode& node)
121 {
122         DataType type = DataType::AUDIO;
123         const XMLProperty* prop = node.property("type");
124         if (prop) {
125                 type = DataType(prop->value());
126         }
127
128         if (type == DataType::AUDIO) {
129                 
130                 if (node.property (X_("destructive")) != 0) {
131                         
132                         boost::shared_ptr<Source> ret (new DestructiveFileSource (s, node));
133                         if (setup_peakfile (ret)) {
134                                 return boost::shared_ptr<Source>();
135                         }
136                         SourceCreated (ret);
137                         return ret;
138
139                 } else {
140                         
141                         boost::shared_ptr<Source> ret (new SndFileSource (s, node));
142                         if (setup_peakfile (ret)) {
143                                 return boost::shared_ptr<Source>();
144                         }
145                         SourceCreated (ret);
146                         return ret;
147                 }
148
149         } else if (type == DataType::MIDI) {
150
151                 boost::shared_ptr<Source> ret (new SMFSource (s, node));
152                 SourceCreated (ret);
153                 return ret;
154
155         }
156         
157         return boost::shared_ptr<Source> ();
158 }
159
160 #endif // HAVE_COREAUDIO
161
162 #ifdef HAVE_COREAUDIO
163 boost::shared_ptr<Source>
164 SourceFactory::createReadable (DataType type, Session& s, string idstr, AudioFileSource::Flag flags, bool announce)
165 {
166         if (type == DataType::AUDIO) {
167                 if (flags & Destructive) {
168                         boost::shared_ptr<Source> ret (new DestructiveFileSource (s, idstr, flags));
169                         if (setup_peakfile (ret)) {
170                                 return boost::shared_ptr<Source>();
171                         }
172                         if (announce) {
173                                 SourceCreated (ret);
174                         }
175                         return ret;
176         
177                         try {
178                                 boost::shared_ptr<Source> ret (new CoreAudioSource (s, idstr, flags));
179                                 if (announce) {
180                                         SourceCreated (ret);
181                                 }
182                                 return ret;
183                 
184                         } catch (failed_constructor& err) {
185                                 boost::shared_ptr<Source> ret (new SndFileSource (s, idstr, flags));
186                                 if (announce) {
187                                         SourceCreated (ret);
188                                 }
189                                 return ret;
190                         }
191
192         } else if (type == DataType::MIDI) {
193
194                 boost::shared_ptr<Source> ret (new SMFSource (s, node));
195                 SourceCreated (ret);
196                 return ret;
197
198         }
199         
200         return boost::shared_ptr<Source>();
201 }
202
203 #else
204
205 boost::shared_ptr<Source>
206 SourceFactory::createReadable (DataType type, Session& s, string idstr, AudioFileSource::Flag flags, bool announce)
207 {
208         if (type == DataType::AUDIO) {
209         
210                 boost::shared_ptr<Source> ret (new SndFileSource (s, idstr, flags));
211                 if (setup_peakfile (ret)) {
212                         return boost::shared_ptr<Source>();
213                 }
214                 if (announce) {
215                         SourceCreated (ret);
216                 }
217                 return ret;
218
219         } else if (type == DataType::MIDI) {
220
221                 boost::shared_ptr<Source> ret (new SMFSource (s, idstr, SMFSource::Flag(0))); // FIXME: flags?
222                 if (announce) {
223                         SourceCreated (ret);
224                 }
225                 return ret;
226
227         }
228         
229         return boost::shared_ptr<Source> ();
230 }
231
232 #endif // HAVE_COREAUDIO
233
234 boost::shared_ptr<Source>
235 SourceFactory::createWritable (DataType type, Session& s, std::string path, bool destructive, nframes_t rate, bool announce)
236 {
237         /* this might throw failed_constructor(), which is OK */
238         if (type == DataType::AUDIO) {
239         
240                 if (destructive) {
241                         boost::shared_ptr<Source> ret (new DestructiveFileSource (s, path,
242                                                 Config->get_native_file_data_format(),
243                                                 Config->get_native_file_header_format(),
244                                                 rate));
245                         if (setup_peakfile (ret)) {
246                                 return boost::shared_ptr<Source>();
247                         }
248                         if (announce) {
249                                 SourceCreated (ret);
250                         }
251                 } else {
252                         boost::shared_ptr<Source> ret (new SndFileSource (s, path, 
253                                                 Config->get_native_file_data_format(),
254                                                 Config->get_native_file_header_format(),
255                                                 rate));
256                         if (setup_peakfile (ret)) {
257                                 return boost::shared_ptr<Source>();
258                         }
259                         if (announce) {
260                                 SourceCreated (ret);
261                         }
262                         return ret;
263                 }
264
265         } else if (type == DataType::MIDI) {
266
267                 boost::shared_ptr<Source> ret (new SMFSource (s, path));
268                 SourceCreated (ret);
269                 return ret;
270         
271         }
272
273         return boost::shared_ptr<Source> ();
274 }