560bf03e7f5eb802063c1f3636300f2af88e3fe7
[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                 try {
68                         boost::shared_ptr<Source> ret (new CoreAudioSource (s, node));
69                         if (setup_peakfile (ret)) {
70                                 return boost::shared_ptr<Source>();
71                         }
72                         SourceCreated (ret);
73                         return ret;
74                 } 
75
76                 catch (failed_constructor& err) {
77                         boost::shared_ptr<Source> ret (new SndFileSource (s, node));
78                         if (setup_peakfile (ret)) {
79                                 return boost::shared_ptr<Source>();
80                         }
81                         SourceCreated (ret);
82                         return ret;
83                 }
84
85         } else if (type == DataType::MIDI) {
86
87                 boost::shared_ptr<Source> ret (new SMFSource (node));
88                 SourceCreated (ret);
89                 return ret;
90
91         }
92
93         return boost::shared_ptr<Source>();
94 }
95
96 #else
97
98 boost::shared_ptr<Source>
99 SourceFactory::create (Session& s, const XMLNode& node)
100 {
101         DataType type = DataType::AUDIO;
102         const XMLProperty* prop = node.property("type");
103         if (prop) {
104                 type = DataType(prop->value());
105         }
106
107         if (type == DataType::AUDIO) {
108                 
109                 boost::shared_ptr<Source> ret (new SndFileSource (s, node));
110
111                 if (setup_peakfile (ret)) {
112                         return boost::shared_ptr<Source>();
113                 }
114                 
115                 SourceCreated (ret);
116                 return ret;
117
118         } else if (type == DataType::MIDI) {
119
120                 boost::shared_ptr<Source> ret (new SMFSource (s, node));
121                 
122                 SourceCreated (ret);
123                 return ret;
124
125         }
126
127         return boost::shared_ptr<Source> ();
128 }
129
130 #endif // HAVE_COREAUDIO
131
132 #ifdef HAVE_COREAUDIO
133 boost::shared_ptr<Source>
134 SourceFactory::createReadable (DataType type, Session& s, string path, int chn, AudioFileSource::Flag flags, bool announce)
135 {
136         if (type == DataType::AUDIO) {
137                 if (!(flags & Destructive)) {
138
139                         try {
140                                 boost::shared_ptr<Source> ret (new CoreAudioSource (s, path, chn, flags));
141                                 if (setup_peakfile (ret)) {
142                                         return boost::shared_ptr<Source>();
143                                 }
144                                 if (announce) {
145                                         SourceCreated (ret);
146                                 }
147                                 return ret;
148                         }
149
150                         catch (failed_constructor& err) {
151                                 boost::shared_ptr<Source> ret (new SndFileSource (s, path, chn, flags));
152                                 if (setup_peakfile (ret)) {
153                                         return boost::shared_ptr<Source>();
154                                 }
155                                 if (announce) {
156                                         SourceCreated (ret);
157                                 }
158                                 return ret;
159                         }
160
161                 } else {
162
163                         boost::shared_ptr<Source> ret (new SndFileSource (s, path, chn, flags));
164                         if (setup_peakfile (ret)) {
165                                 return boost::shared_ptr<Source>();
166                         }
167                         if (announce) {
168                                 SourceCreated (ret);
169                         }
170                         return ret;
171                 }
172
173                 return boost::shared_ptr<Source>();
174         } else if (type == DataType::MIDI) {
175
176                 boost::shared_ptr<Source> ret (new SMFSource (s, node));
177                 if (announce) {
178                         SourceCreated (ret);
179                 }
180                 return ret;
181
182         }
183
184         return boost::shared_ptr<Source>();
185 }
186
187 #else
188
189 boost::shared_ptr<Source>
190 SourceFactory::createReadable (DataType type, Session& s, string path, int chn, AudioFileSource::Flag flags, bool announce)
191 {
192         if (type == DataType::AUDIO) {
193         
194                 boost::shared_ptr<Source> ret (new SndFileSource (s, path, chn, flags));
195
196                 if (setup_peakfile (ret)) {
197                         return boost::shared_ptr<Source>();
198                 }
199
200                 if (announce) {
201                         SourceCreated (ret);
202                 }
203
204                 return ret;
205
206
207         } else if (type == DataType::MIDI) {
208
209                 // FIXME: flags?
210                 boost::shared_ptr<Source> ret (new SMFSource (s, path, SMFSource::Flag(0)));
211
212                 if (announce) {
213                         SourceCreated (ret);
214                 }
215
216                 return ret;
217         }
218
219         return boost::shared_ptr<Source>();
220 }
221
222 #endif // HAVE_COREAUDIO
223
224 boost::shared_ptr<Source>
225 SourceFactory::createWritable (DataType type, Session& s, std::string path, bool destructive, nframes_t rate, bool announce)
226 {
227         /* this might throw failed_constructor(), which is OK */
228
229         if (type == DataType::AUDIO) {
230                 boost::shared_ptr<Source> ret (new SndFileSource 
231                                 (s, path, 
232                                  Config->get_native_file_data_format(),
233                                  Config->get_native_file_header_format(),
234                                  rate,
235                                  (destructive ? AudioFileSource::Flag (SndFileSource::default_writable_flags | AudioFileSource::Destructive) :
236                                   SndFileSource::default_writable_flags)));     
237
238                 if (setup_peakfile (ret)) {
239                         return boost::shared_ptr<Source>();
240                 }
241                 if (announce) {
242                         SourceCreated (ret);
243                 }
244                 return ret;
245
246         } else if (type == DataType::MIDI) {
247
248                 boost::shared_ptr<Source> ret (new SMFSource (s, path));
249                 
250                 if (announce) {
251                         SourceCreated (ret);
252                 }
253                 return ret;
254
255         }
256
257         return boost::shared_ptr<Source> ();
258 }