2 * Copyright (C) 2008-2017 Paul Davis <paul@linuxaudiosystems.com>
3 * Copyright (C) 2009 David Robillard <d@drobilla.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "ardour/caimportable.h"
22 #include "pbd/error.h"
26 using namespace ARDOUR;
30 CAImportableSource::CAImportableSource (const string& path)
33 af.Open (path.c_str());
35 CAStreamBasicDescription file_format (af.GetFileDataFormat());
36 CAStreamBasicDescription client_format (file_format);
38 /* set canonial form (PCM, native float packed, 32 bit, with the correct number of channels
39 and interleaved (since we plan to deinterleave ourselves)
42 client_format.SetCanonical(client_format.NumberChannels(), true);
43 af.SetClientFormat (client_format);
45 } catch (CAXException& cax) {
46 //Don't report an error here since there is one higher up in import.
47 //Since libsndfile gets tried second, any failures here may show as
48 //invalid errors in the Error log.
49 throw failed_constructor ();
54 CAImportableSource::~CAImportableSource ()
59 CAImportableSource::read (Sample* buffer, samplecnt_t nframes)
61 samplecnt_t nread = 0;
63 samplecnt_t per_channel;
66 abl.mNumberBuffers = 1;
67 abl.mBuffers[0].mNumberChannels = channels();
69 per_channel = nframes / abl.mBuffers[0].mNumberChannels;
71 while (nread < per_channel) {
73 UInt32 new_cnt = per_channel - nread;
75 abl.mBuffers[0].mDataByteSize = new_cnt * abl.mBuffers[0].mNumberChannels * sizeof(Sample);
76 abl.mBuffers[0].mData = buffer + nread;
79 af.Read (new_cnt, &abl);
80 } catch (CAXException& cax) {
81 error << string_compose("CAImportable: %1", cax.mOperation);
94 if (!at_end && nread < per_channel) {
97 return nread * abl.mBuffers[0].mNumberChannels;
102 CAImportableSource::channels () const
104 return af.GetFileDataFormat().NumberChannels();
108 CAImportableSource::length () const
110 return af.GetNumberFrames();
114 CAImportableSource::samplerate () const
116 CAStreamBasicDescription client_asbd;
119 client_asbd = af.GetClientDataFormat ();
120 } catch (CAXException& cax) {
121 error << string_compose ("CAImportable: %1", cax.mOperation) << endmsg;
125 return client_asbd.mSampleRate;
129 CAImportableSource::seek (samplepos_t pos)
133 } catch (CAXException& cax) {
134 error << string_compose ("CAImportable: %1 to %2", cax.mOperation, pos) << endmsg;
140 CAImportableSource::natural_position () const
142 // TODO: extract timecode, if any