From fdda19d3d45384fb4f158e4f1af18cc17009e478 Mon Sep 17 00:00:00 2001 From: Taybin Rutkin Date: Tue, 27 Jun 2006 21:57:15 +0000 Subject: CoreAudioSource moved to coreaudiosource.cc. Compiles with new libsndfile class hierarchy. git-svn-id: svn://localhost/ardour2/trunk@647 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/coreaudiosource.cc | 218 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 libs/ardour/coreaudiosource.cc (limited to 'libs/ardour/coreaudiosource.cc') diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc new file mode 100644 index 0000000000..55409a8524 --- /dev/null +++ b/libs/ardour/coreaudiosource.cc @@ -0,0 +1,218 @@ +/* + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include + +#include "i18n.h" + +#include + +using namespace ARDOUR; +using namespace PBD; + +CoreAudioSource::CoreAudioSource (const XMLNode& node) + : AudioFileSource (node) +{ + init (_name); + + AudioSourceCreated (this); /* EMIT SIGNAL */ +} + +CoreAudioSource::CoreAudioSource (const string& idstr, Flag flags) + : AudioFileSource(idstr, flags) +{ + init (idstr); + + AudioSourceCreated (this); /* EMIT SIGNAL */ +} + +void +CoreAudioSource::init (const string& idstr) +{ + string::size_type pos; + string file; + + tmpbuf = 0; + tmpbufsize = 0; + af = 0; + OSStatus err = noErr; + + _name = idstr; + + if ((pos = idstr.find_last_of (':')) == string::npos) { + channel = 0; + file = idstr; + } else { + channel = atoi (idstr.substr (pos+1).c_str()); + file = idstr.substr (0, pos); + } + + /* note that we temporarily truncated _id at the colon */ + FSRef fsr; + err = FSPathMakeRef ((UInt8*)file.c_str(), &fsr, 0); + if (err != noErr) { + cerr << "FSPathMakeRef " << err << endl; + throw failed_constructor(); + } + + 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 >= 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(); + } + + 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_peakfiles) { + if (initialize_peakfile (false, file)) { + error << "initialize peakfile failed" << endmsg; + ExtAudioFileDispose (af); + throw failed_constructor (); + } + } +} + +CoreAudioSource::~CoreAudioSource () +{ + GoingAway (this); /* EMIT SIGNAL */ + + if (af) { + ExtAudioFileDispose (af); + } + + if (tmpbuf) { + delete [] tmpbuf; + } +} + +jack_nframes_t +CoreAudioSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const +{ + OSStatus err = noErr; + + 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; + } + + 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 cnt; + } + + uint32_t real_cnt = cnt * n_channels; + + { + Glib::Mutex::Lock lm (_tmpbuf_lock); + + if (tmpbufsize < real_cnt) { + + if (tmpbuf) { + delete [] tmpbuf; + } + tmpbufsize = real_cnt; + tmpbuf = new float[tmpbufsize]; + } + + abl.mBuffers[0].mDataByteSize = real_cnt * sizeof(Sample); + abl.mBuffers[0].mData = tmpbuf; + + err = ExtAudioFileRead(af, (UInt32*) &real_cnt, &abl); + float *ptr = tmpbuf + channel; + real_cnt /= n_channels; + + /* stride through the interleaved data */ + + for (uint32_t n = 0; n < real_cnt; ++n) { + dst[n] = *ptr; + ptr += n_channels; + } + } + + _read_data_count = cnt * sizeof(float); + + return real_cnt; +} + +float +CoreAudioSource::sample_rate() const +{ + /* XXX taybin fill me in please */ + + return 44100.0f; +} -- cgit v1.2.3