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