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);
80 snprintf (buf, sizeof (buf), "%u-%u-%d.peak", stat_mount.st_ino, stat_file.st_ino, channel);
82 snprintf (buf, sizeof (buf), "%ld-%ld-%d.peak", stat_mount.st_ino, stat_file.st_ino, channel);
85 string res = peak_dir;
94 ExternalSource::create (const XMLNode& node)
96 ExternalSource* es = 0;
99 es = new CoreAudioSource (node);
102 catch (failed_constructor& err) {
103 es = new SndFileSource (node);
106 es = new SndFileSource (node);
114 ExternalSource::create (const XMLNode& node)
116 return new SndFileSource (node);
119 #endif // HAVE_COREAUDIO
121 #ifdef HAVE_COREAUDIO
123 ExternalSource::create (const string& idstr, bool build_peak)
125 ExternalSource* es = 0;
128 es = new CoreAudioSource (idstr, build_peak);
131 catch (failed_constructor& err) {
132 es = new SndFileSource (idstr, build_peak);
141 ExternalSource::create (const string& idstr, bool build_peak)
143 return new SndFileSource (idstr, build_peak);
146 #endif // HAVE_COREAUDIO
148 #ifdef HAVE_COREAUDIO
150 CFStringRefToStdString(CFStringRef stringRef)
153 CFStringGetMaximumSizeForEncoding(CFStringGetLength(stringRef) ,
154 kCFStringEncodingASCII);
155 char *buf = new char[size];
159 if(CFStringGetCString(stringRef, buf, size, kCFStringEncodingASCII)) {
165 #endif // HAVE_COREAUDIO
168 ExternalSource::get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg)
170 #ifdef HAVE_COREAUDIO
171 OSStatus err = noErr;
173 ExtAudioFileRef af = 0;
177 err = FSPathMakeRef ((UInt8*)path.c_str(), &ref, 0);
179 ExtAudioFileDispose (af);
183 err = ExtAudioFileOpen(&ref, &af);
185 ExtAudioFileDispose (af);
189 AudioStreamBasicDescription absd;
190 memset(&absd, 0, sizeof(absd));
191 size = sizeof(AudioStreamBasicDescription);
192 err = ExtAudioFileGetProperty(af,
193 kExtAudioFileProperty_FileDataFormat, &size, &absd);
195 ExtAudioFileDispose (af);
199 _info.samplerate = absd.mSampleRate;
200 _info.channels = absd.mChannelsPerFrame;
202 size = sizeof(_info.length);
203 err = ExtAudioFileGetProperty(af, kExtAudioFileProperty_FileLengthFrames, &size, &_info.length);
205 ExtAudioFileDispose (af);
209 size = sizeof(CFStringRef);
210 err = AudioFormatGetProperty(
211 kAudioFormatProperty_FormatName, sizeof(absd), &absd, &size, &name);
213 ExtAudioFileDispose (af);
217 _info.format_name = CFStringRefToStdString(name);
219 ExtAudioFileDispose (af);
223 #endif // HAVE_COREAUDIO
228 sf_info.format = 0; // libsndfile says to clear this before sf_open().
230 if ((sf = sf_open ((char*) path.c_str(), SFM_READ, &sf_info)) == 0) {
232 error_msg = sf_error_str (0, errbuf, sizeof (errbuf) - 1);
238 _info.samplerate = sf_info.samplerate;
239 _info.channels = sf_info.channels;
240 _info.length = sf_info.frames;
241 _info.format_name = string_compose("Format: %1, %2",
242 sndfile_major_format(sf_info.format),
243 sndfile_minor_format(sf_info.format));