Remove all use of nframes_t.
[ardour.git] / libs / ardour / caimportable.cc
1 #include "ardour/caimportable.h"
2 #include <sndfile.h>
3 #include "pbd/error.h"
4
5 #include "i18n.h"
6
7 using namespace ARDOUR;
8 using namespace std;
9 using namespace PBD;
10
11 CAImportableSource::CAImportableSource (const string& path)
12 {
13         try {
14                 af.Open (path.c_str());
15
16                 CAStreamBasicDescription file_format (af.GetFileDataFormat());
17                 CAStreamBasicDescription client_format (file_format);
18
19                 /* set canonial form (PCM, native float packed, 32 bit, with the correct number of channels
20                    and interleaved (since we plan to deinterleave ourselves)
21                 */
22
23                 client_format.SetCanonical(client_format.NumberChannels(), true);
24                 af.SetClientFormat (client_format);
25
26         } catch (CAXException& cax) {
27                 //Don't report an error here since there is one higher up in import.
28                 //Since libsndfile gets tried second, any failures here may show as
29                 //invalid errors in the Error log.
30                 throw failed_constructor ();
31         }
32
33 }
34
35 CAImportableSource::~CAImportableSource ()
36 {
37 }
38
39 framecnt_t
40 CAImportableSource::read (Sample* buffer, framecnt_t nframes)
41 {
42         framecnt_t nread = 0;
43         AudioBufferList abl;
44         framecnt_t per_channel;
45         bool at_end = false;
46
47         abl.mNumberBuffers = 1;
48         abl.mBuffers[0].mNumberChannels = channels();
49
50         per_channel = nframes / abl.mBuffers[0].mNumberChannels;
51
52         while (nread < per_channel) {
53
54                 UInt32 new_cnt = per_channel - nread;
55
56                 abl.mBuffers[0].mDataByteSize = new_cnt * abl.mBuffers[0].mNumberChannels * sizeof(Sample);
57                 abl.mBuffers[0].mData = buffer + nread;
58
59                 try {
60                         af.Read (new_cnt, &abl);
61                 } catch (CAXException& cax) {
62                         error << string_compose("CAImportable: %1", cax.mOperation);
63                         return -1;
64                 }
65
66                 if (new_cnt == 0) {
67                         /* EOF */
68                         at_end = true;
69                         break;
70                 }
71
72                 nread += new_cnt;
73         }
74
75         if (!at_end && nread < per_channel) {
76                 return 0;
77         } else {
78                 return nread * abl.mBuffers[0].mNumberChannels;
79         }
80 }
81
82 uint
83 CAImportableSource::channels () const
84 {
85         return af.GetFileDataFormat().NumberChannels();
86 }
87
88 framecnt_t
89 CAImportableSource::length () const
90 {
91         return af.GetNumberFrames();
92 }
93
94 framecnt_t
95 CAImportableSource::samplerate () const
96 {
97         CAStreamBasicDescription client_asbd;
98
99         try {
100                 client_asbd = af.GetClientDataFormat ();
101         } catch (CAXException& cax) {
102                 error << string_compose ("CAImportable: %1", cax.mOperation) << endmsg;
103                 return 0.0;
104         }
105
106         return client_asbd.mSampleRate;
107 }
108
109 void
110 CAImportableSource::seek (framepos_t pos)
111 {
112         try {
113                 af.Seek (pos);
114         } catch (CAXException& cax) {
115                 error << string_compose ("CAImportable: %1 to %2", cax.mOperation, pos) << endmsg;
116         }
117 }
118
119
120