148f737551c760f8193442dd4acb711635e49a50
[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 boost::shared_ptr<Source>
64 SourceFactory::create (Session& s, const XMLNode& node)
65 {
66         /* this is allowed to throw */
67
68         DataType type = DataType::AUDIO;
69         const XMLProperty* prop = node.property("type");
70         if (prop) {
71                 type = DataType(prop->value());
72         }
73         
74         if (type == DataType::AUDIO) {
75                 
76 #ifdef HAVE_COREAUDIO
77                 try {
78                         boost::shared_ptr<Source> ret (new CoreAudioSource (s, node));
79                         if (setup_peakfile (ret)) {
80                                 return boost::shared_ptr<Source>();
81                         }
82                         SourceCreated (ret);
83                         return ret;
84                 } 
85
86                 catch (failed_constructor& err) {
87                 
88                         /* this is allowed to throw */
89                         
90                         boost::shared_ptr<Source> ret (new SndFileSource (s, node));
91                         if (setup_peakfile (ret)) {
92                                 return boost::shared_ptr<Source>();
93                         }
94                         SourceCreated (ret);
95                         return ret;
96                 }
97 #else
98                 boost::shared_ptr<Source> ret (new SndFileSource (s, node));
99
100                 if (setup_peakfile (ret)) {
101                         return boost::shared_ptr<Source>();
102                 }
103                 
104                 SourceCreated (ret);
105                 return ret;
106 #endif
107
108         } else if (type == DataType::MIDI) {
109
110                 boost::shared_ptr<Source> ret (new SMFSource (s, node));
111                 
112                 SourceCreated (ret);
113                 return ret;
114
115         }
116         
117         return boost::shared_ptr<Source> ();
118 }
119
120 boost::shared_ptr<Source>
121 SourceFactory::createReadable (DataType type, Session& s, string path, int chn, AudioFileSource::Flag flags, bool announce)
122 {
123         if (type == DataType::AUDIO) {
124         
125 #ifdef HAVE_COREAUDIO
126                 try {
127                         boost::shared_ptr<Source> ret (new CoreAudioSource (s, path, chn, flags));
128                         if (setup_peakfile (ret)) {
129                                 return boost::shared_ptr<Source>();
130                         }
131                         if (announce) {
132                                 SourceCreated (ret);
133                         }
134                         return ret;
135                 }
136
137                 catch (failed_constructor& err) {
138                         boost::shared_ptr<Source> ret (new SndFileSource (s, path, chn, flags));
139                         if (setup_peakfile (ret)) {
140                                 return boost::shared_ptr<Source>();
141                         }
142                         if (announce) {
143                                 SourceCreated (ret);
144                         }
145                         return ret;
146                 }
147 #else
148                 boost::shared_ptr<Source> ret (new SndFileSource (s, path, chn, flags));
149
150                 if (setup_peakfile (ret)) {
151                         return boost::shared_ptr<Source>();
152                 }
153
154                 if (announce) {
155                         SourceCreated (ret);
156                 }
157
158                 return ret;
159 #endif
160
161         } else if (type == DataType::MIDI) {
162
163                 // FIXME: flags?
164                 boost::shared_ptr<Source> ret (new SMFSource (s, path, SMFSource::Flag(0)));
165
166                 if (announce) {
167                         SourceCreated (ret);
168                 }
169
170                 return ret;
171         }
172
173         return boost::shared_ptr<Source>();
174 }
175
176 boost::shared_ptr<Source>
177 SourceFactory::createWritable (DataType type, Session& s, std::string path, bool destructive, nframes_t rate, bool announce)
178 {
179         /* this might throw failed_constructor(), which is OK */
180
181         if (type == DataType::AUDIO) {
182                 boost::shared_ptr<Source> ret (new SndFileSource 
183                                 (s, path, 
184                                  Config->get_native_file_data_format(),
185                                  Config->get_native_file_header_format(),
186                                  rate,
187                                  (destructive ? AudioFileSource::Flag (SndFileSource::default_writable_flags | AudioFileSource::Destructive) :
188                                   SndFileSource::default_writable_flags)));     
189
190                 if (setup_peakfile (ret)) {
191                         return boost::shared_ptr<Source>();
192                 }
193                 if (announce) {
194                         SourceCreated (ret);
195                 }
196                 return ret;
197
198         } else if (type == DataType::MIDI) {
199
200                 boost::shared_ptr<Source> ret (new SMFSource (s, path));
201                 
202                 if (announce) {
203                         SourceCreated (ret);
204                 }
205                 return ret;
206
207         }
208
209         return boost::shared_ptr<Source> ();
210 }