2 Copyright (C) 2006 Paul Davis
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.
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.
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.
26 #include <pbd/mountpoint.h>
27 #include <ardour/externalsource.h>
28 #include <ardour/sndfilesource.h>
29 #include <ardour/sndfile_helpers.h>
31 // if these headers come before sigc++ is included
32 // the parser throws ObjC++ errors. (nil is a keyword)
34 #include <ardour/coreaudio_source.h>
35 #include <AudioToolbox/ExtendedAudioFile.h>
36 #include <AudioToolbox/AudioFormat.h>
37 #endif // HAVE_COREAUDIO
41 using namespace ARDOUR;
43 string ExternalSource::peak_dir = "";
45 ExternalSource::ExternalSource (const XMLNode& node)
50 ExternalSource::ExternalSource (const string& idstr, bool build_peak)
55 ExternalSource::~ExternalSource ()
60 ExternalSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
62 return read (dst, start, cnt, workbuf);
66 ExternalSource::peak_path (string audio_path)
68 /* XXX hardly bombproof! fix me */
70 struct stat stat_file;
71 struct stat stat_mount;
73 string mp = mountpoint (audio_path);
75 stat (audio_path.c_str(), &stat_file);
76 stat (mp.c_str(), &stat_mount);
79 snprintf (buf, sizeof (buf), "%ld-%ld-%d.peak", stat_mount.st_ino, stat_file.st_ino, channel);
81 string res = peak_dir;
90 ExternalSource::create (const XMLNode& node)
92 ExternalSource* es = 0;
95 es = new CoreAudioSource (node);
98 catch (failed_constructor& err) {
99 es = new SndFileSource (node);
102 es = new SndFileSource (node);
110 ExternalSource::create (const XMLNode& node)
112 return new SndFileSource (node);
115 #endif // HAVE_COREAUDIO
117 #ifdef HAVE_COREAUDIO
119 ExternalSource::create (const string& idstr, bool build_peak)
121 ExternalSource* es = 0;
124 es = new CoreAudioSource (idstr, build_peak);
127 catch (failed_constructor& err) {
128 es = new SndFileSource (idstr, build_peak);
137 ExternalSource::create (const string& idstr, bool build_peak)
139 return new SndFileSource (idstr, build_peak);
142 #endif // HAVE_COREAUDIO
144 #ifdef HAVE_COREAUDIO
146 CFStringRefToStdString(CFStringRef stringRef)
149 CFStringGetMaximumSizeForEncoding(CFStringGetLength(stringRef) ,
150 kCFStringEncodingASCII);
151 char *buf = new char[size];
155 if(CFStringGetCString(stringRef, buf, size, kCFStringEncodingASCII)) {
161 #endif // HAVE_COREAUDIO
164 ExternalSource::get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg)
166 #ifdef HAVE_COREAUDIO
167 OSStatus err = noErr;
169 ExtAudioFileRef af = 0;
173 err = FSPathMakeRef ((UInt8*)path.c_str(), &ref, 0);
175 ExtAudioFileDispose (af);
179 err = ExtAudioFileOpen(&ref, &af);
181 ExtAudioFileDispose (af);
185 AudioStreamBasicDescription absd;
186 memset(&absd, 0, sizeof(absd));
187 size = sizeof(AudioStreamBasicDescription);
188 err = ExtAudioFileGetProperty(af,
189 kExtAudioFileProperty_FileDataFormat, &size, &absd);
191 ExtAudioFileDispose (af);
195 _info.samplerate = absd.mSampleRate;
196 _info.channels = absd.mChannelsPerFrame;
198 size = sizeof(_info.length);
199 err = ExtAudioFileGetProperty(af, kExtAudioFileProperty_FileLengthFrames, &size, &_info.length);
201 ExtAudioFileDispose (af);
205 size = sizeof(CFStringRef);
206 err = AudioFormatGetProperty(
207 kAudioFormatProperty_FormatName, sizeof(absd), &absd, &size, &name);
209 ExtAudioFileDispose (af);
213 _info.format_name = CFStringRefToStdString(name);
215 ExtAudioFileDispose (af);
219 #endif // HAVE_COREAUDIO
224 sf_info.format = 0; // libsndfile says to clear this before sf_open().
226 if ((sf = sf_open ((char*) path.c_str(), SFM_READ, &sf_info)) == 0) {
228 error_msg = sf_error_str (0, errbuf, sizeof (errbuf) - 1);
234 _info.samplerate = sf_info.samplerate;
235 _info.channels = sf_info.channels;
236 _info.length = sf_info.frames;
237 _info.format_name = string_compose("Format: %1, %2",
238 sndfile_major_format(sf_info.format),
239 sndfile_minor_format(sf_info.format));