/*
- Copyright (C) 2000 Paul Davis
+ Copyright (C) 2006 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id$
*/
-#include <string>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/time.h>
+#include <pbd/error.h>
-#include <pbd/mountpoint.h>
#include <ardour/coreaudio_source.h>
#include "i18n.h"
-using namespace ARDOUR;
+#include <AudioToolbox/AudioFormat.h>
-string CoreAudioSource::peak_dir = "";
+using namespace ARDOUR;
+using namespace PBD;
CoreAudioSource::CoreAudioSource (const XMLNode& node)
- : Source (node)
+ : AudioFileSource (node)
{
- if (set_state (node)) {
- throw failed_constructor();
- }
-
init (_name, true);
- SourceCreated (this); /* EMIT SIGNAL */
+ AudioSourceCreated (this); /* EMIT SIGNAL */
}
CoreAudioSource::CoreAudioSource (const string& idstr, bool build_peak)
- : Source(build_peak)
+ : AudioFileSource(idstr, build_peak)
{
init (idstr, build_peak);
if (build_peak) {
- SourceCreated (this); /* EMIT SIGNAL */
+ AudioSourceCreated (this); /* EMIT SIGNAL */
}
}
tmpbuf = 0;
tmpbufsize = 0;
- sf = 0;
+ af = 0;
+ OSStatus err = noErr;
_name = idstr;
}
/* note that we temporarily truncated _id at the colon */
- FSRef* ref;
- OSStatus err = FSPathMakeRef (file.c_str(), ref, 0);
- if (err) {
+ FSRef fsr;
+ err = FSPathMakeRef ((UInt8*)file.c_str(), &fsr, 0);
+ if (err != noErr) {
+ cerr << "FSPathMakeRef " << err << endl;
throw failed_constructor();
}
- err = AudioFileOpen (ref, fsCurPerm, 0, sf);
- if (err) {
+
+ err = ExtAudioFileOpen (&fsr, &af);
+ if (err != noErr) {
+ cerr << "ExtAudioFileOpen " << err << endl;
+ ExtAudioFileDispose (af);
throw failed_constructor();
}
+
+ AudioStreamBasicDescription file_asbd;
+ memset(&file_asbd, 0, sizeof(AudioStreamBasicDescription));
+ size_t asbd_size = sizeof(AudioStreamBasicDescription);
+ err = ExtAudioFileGetProperty(af,
+ kExtAudioFileProperty_FileDataFormat, &asbd_size, &file_asbd);
+ if (err != noErr) {
+ cerr << "ExtAudioFileGetProperty1 " << err << endl;
+ ExtAudioFileDispose (af);
+ throw failed_constructor();
+ }
+ n_channels = file_asbd.mChannelsPerFrame;
+
+ cerr << "number of channels: " << n_channels << endl;
- if (channel >= _info.channels) {
- error << string_compose(_("CoreAudioSource: file only contains %1 channels; %2 is invalid as a channel number"), _info.channels, channel) << endmsg;
- sf_close (sf);
- sf = 0;
+ if (channel >= n_channels) {
+ error << string_compose(_("CoreAudioSource: file only contains %1 channels; %2 is invalid as a channel number"), n_channels, channel) << endmsg;
+ ExtAudioFileDispose (af);
throw failed_constructor();
}
- _length = _info.frames;
+ int64_t ca_frames;
+ size_t prop_size = sizeof(int64_t);
+
+ err = ExtAudioFileGetProperty(af, kExtAudioFileProperty_FileLengthFrames, &prop_size, &ca_frames);
+ if (err != noErr) {
+ cerr << "ExtAudioFileGetProperty2 " << err << endl;
+ ExtAudioFileDispose (af);
+ throw failed_constructor();
+ }
+
+ _length = ca_frames;
_path = file;
+ AudioStreamBasicDescription client_asbd;
+ memset(&client_asbd, 0, sizeof(AudioStreamBasicDescription));
+ client_asbd.mSampleRate = file_asbd.mSampleRate;
+ client_asbd.mFormatID = kAudioFormatLinearPCM;
+ client_asbd.mFormatFlags = kLinearPCMFormatFlagIsFloat;
+ client_asbd.mBytesPerPacket = file_asbd.mChannelsPerFrame * 4;
+ client_asbd.mFramesPerPacket = 1;
+ client_asbd.mBytesPerFrame = client_asbd.mBytesPerPacket;
+ client_asbd.mChannelsPerFrame = file_asbd.mChannelsPerFrame;
+ client_asbd.mBitsPerChannel = 32;
+
+ err = ExtAudioFileSetProperty (af, kExtAudioFileProperty_ClientDataFormat, asbd_size, &client_asbd);
+ if (err != noErr) {
+ cerr << "ExtAudioFileSetProperty3 " << err << endl;
+ ExtAudioFileDispose (af);
+ throw failed_constructor ();
+ }
+
if (build_peak) {
if (initialize_peakfile (false, file)) {
- sf_close (sf);
- sf = 0;
+ error << "initialize peakfile failed" << endmsg;
+ ExtAudioFileDispose (af);
throw failed_constructor ();
}
}
}
CoreAudioSource::~CoreAudioSource ()
-
{
- GoingAway (this); /* EMIT SIGNAL */
+ GoingAway (this); /* EMIT SIGNAL */
- if (sf) {
- sf_close (sf);
+ if (af) {
+ ExtAudioFileDispose (af);
}
if (tmpbuf) {
}
jack_nframes_t
-CoreAudioSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const
+CoreAudioSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
{
- return read (dst, start, cnt);
-}
+ OSStatus err = noErr;
-jack_nframes_t
-CoreAudioSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const
-{
- int32_t nread;
- float *ptr;
- uint32_t real_cnt;
-
- if (sf_seek (sf, (off_t) start, SEEK_SET) < 0) {
- char errbuf[256];
- sf_error_str (0, errbuf, sizeof (errbuf) - 1);
- error << string_compose(_("CoreAudioSource: could not seek to frame %1 within %2 (%3)"), start, _name.substr (1), errbuf) << endmsg;
+ err = ExtAudioFileSeek(af, start);
+ if (err != noErr) {
+ error << string_compose(_("CoreAudioSource: could not seek to frame %1 within %2 (%3)"), start, _name.substr (1), err) << endmsg;
return 0;
}
- if (_info.channels == 1) {
- jack_nframes_t ret = sf_read_float (sf, dst, cnt);
+ AudioBufferList abl;
+ abl.mNumberBuffers = 1;
+ abl.mBuffers[0].mNumberChannels = n_channels;
+ abl.mBuffers[0].mDataByteSize = cnt * sizeof(Sample);
+ abl.mBuffers[0].mData = dst;
+
+ if (n_channels == 1) {
+ err = ExtAudioFileRead(af, (UInt32*) &cnt, &abl);
_read_data_count = cnt * sizeof(float);
- return ret;
+ return cnt;
}
- real_cnt = cnt * _info.channels;
+ uint32_t real_cnt = cnt * n_channels;
{
- LockMonitor lm (_tmpbuf_lock, __LINE__, __FILE__);
+ Glib::Mutex::Lock lm (_tmpbuf_lock);
if (tmpbufsize < real_cnt) {
tmpbufsize = real_cnt;
tmpbuf = new float[tmpbufsize];
}
+
+ abl.mBuffers[0].mDataByteSize = real_cnt * sizeof(Sample);
+ abl.mBuffers[0].mData = tmpbuf;
- nread = sf_read_float (sf, tmpbuf, real_cnt);
- ptr = tmpbuf + channel;
- nread /= _info.channels;
+ err = ExtAudioFileRead(af, (UInt32*) &real_cnt, &abl);
+ float *ptr = tmpbuf + channel;
+ real_cnt /= n_channels;
/* stride through the interleaved data */
- for (int32_t n = 0; n < nread; ++n) {
+ for (uint32_t n = 0; n < real_cnt; ++n) {
dst[n] = *ptr;
- ptr += _info.channels;
+ ptr += n_channels;
}
}
_read_data_count = cnt * sizeof(float);
- return nread;
+ return real_cnt;
}
-string
-CoreAudioSource::peak_path (string audio_path)
+float
+CoreAudioSource::sample_rate() const
{
- /* XXX hardly bombproof! fix me */
-
- struct stat stat_file;
- struct stat stat_mount;
+ /* XXX taybin fill me in please */
- string mp = mountpoint (audio_path);
-
- stat (audio_path.c_str(), &stat_file);
- stat (mp.c_str(), &stat_mount);
-
- char buf[32];
- snprintf (buf, sizeof (buf), "%ld-%ld-%d.peak", stat_mount.st_ino, stat_file.st_ino, channel);
-
- string res = peak_dir;
- res += buf;
-
- return res;
-}
-
-string
-CoreAudioSource::old_peak_path (string audio_path)
-{
- return peak_path (audio_path);
+ return 44100.0f;
}