enough with umpteen "i18n.h" files. Consolidate on pbd/i18n.h
[ardour.git] / libs / ardour / caimportable.cc
1 /*
2     Copyright (C) 2012 Paul Davis
3
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.
8
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.
13
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.
17
18 */
19
20 #include "ardour/caimportable.h"
21 #include <sndfile.h>
22 #include "pbd/error.h"
23
24 #include "pbd/i18n.h"
25
26 using namespace ARDOUR;
27 using namespace std;
28 using namespace PBD;
29
30 CAImportableSource::CAImportableSource (const string& path)
31 {
32         try {
33                 af.Open (path.c_str());
34
35                 CAStreamBasicDescription file_format (af.GetFileDataFormat());
36                 CAStreamBasicDescription client_format (file_format);
37
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)
40                 */
41
42                 client_format.SetCanonical(client_format.NumberChannels(), true);
43                 af.SetClientFormat (client_format);
44
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 ();
50         }
51
52 }
53
54 CAImportableSource::~CAImportableSource ()
55 {
56 }
57
58 framecnt_t
59 CAImportableSource::read (Sample* buffer, framecnt_t nframes)
60 {
61         framecnt_t nread = 0;
62         AudioBufferList abl;
63         framecnt_t per_channel;
64         bool at_end = false;
65
66         abl.mNumberBuffers = 1;
67         abl.mBuffers[0].mNumberChannels = channels();
68
69         per_channel = nframes / abl.mBuffers[0].mNumberChannels;
70
71         while (nread < per_channel) {
72
73                 UInt32 new_cnt = per_channel - nread;
74
75                 abl.mBuffers[0].mDataByteSize = new_cnt * abl.mBuffers[0].mNumberChannels * sizeof(Sample);
76                 abl.mBuffers[0].mData = buffer + nread;
77
78                 try {
79                         af.Read (new_cnt, &abl);
80                 } catch (CAXException& cax) {
81                         error << string_compose("CAImportable: %1", cax.mOperation);
82                         return -1;
83                 }
84
85                 if (new_cnt == 0) {
86                         /* EOF */
87                         at_end = true;
88                         break;
89                 }
90
91                 nread += new_cnt;
92         }
93
94         if (!at_end && nread < per_channel) {
95                 return 0;
96         } else {
97                 return nread * abl.mBuffers[0].mNumberChannels;
98         }
99 }
100
101 uint
102 CAImportableSource::channels () const
103 {
104         return af.GetFileDataFormat().NumberChannels();
105 }
106
107 framecnt_t
108 CAImportableSource::length () const
109 {
110         return af.GetNumberFrames();
111 }
112
113 framecnt_t
114 CAImportableSource::samplerate () const
115 {
116         CAStreamBasicDescription client_asbd;
117
118         try {
119                 client_asbd = af.GetClientDataFormat ();
120         } catch (CAXException& cax) {
121                 error << string_compose ("CAImportable: %1", cax.mOperation) << endmsg;
122                 return 0.0;
123         }
124
125         return client_asbd.mSampleRate;
126 }
127
128 void
129 CAImportableSource::seek (framepos_t pos)
130 {
131         try {
132                 af.Seek (pos);
133         } catch (CAXException& cax) {
134                 error << string_compose ("CAImportable: %1 to %2", cax.mOperation, pos) << endmsg;
135         }
136 }
137
138
139