Mercurial > hg > svcore
comparison data/fileio/AudioFileReaderFactory.cpp @ 1126:39019ce29178 tony-2.0-integration
Merge through to branch for Tony 2.0
author | Chris Cannam |
---|---|
date | Thu, 20 Aug 2015 14:54:21 +0100 |
parents | cd156ede1395 |
children | 6877f4200912 |
comparison
equal
deleted
inserted
replaced
1119:e22bfe8ca248 | 1126:39019ce29178 |
---|---|
19 #include "DecodingWavFileReader.h" | 19 #include "DecodingWavFileReader.h" |
20 #include "OggVorbisFileReader.h" | 20 #include "OggVorbisFileReader.h" |
21 #include "MP3FileReader.h" | 21 #include "MP3FileReader.h" |
22 #include "QuickTimeFileReader.h" | 22 #include "QuickTimeFileReader.h" |
23 #include "CoreAudioFileReader.h" | 23 #include "CoreAudioFileReader.h" |
24 #include "AudioFileSizeEstimator.h" | |
25 | |
26 #include "base/StorageAdviser.h" | |
24 | 27 |
25 #include <QString> | 28 #include <QString> |
26 #include <QFileInfo> | 29 #include <QFileInfo> |
27 #include <iostream> | 30 #include <iostream> |
28 | 31 |
96 return 0; | 99 return 0; |
97 } | 100 } |
98 | 101 |
99 AudioFileReader *reader = 0; | 102 AudioFileReader *reader = 0; |
100 | 103 |
104 sv_frame_t estimatedSamples = | |
105 AudioFileSizeEstimator::estimate(source, targetRate); | |
106 | |
107 CodedAudioFileReader::CacheMode cacheMode = | |
108 CodedAudioFileReader::CacheInTemporaryFile; | |
109 | |
110 if (estimatedSamples > 0) { | |
111 size_t kb = (estimatedSamples * sizeof(float)) / 1024; | |
112 StorageAdviser::Recommendation rec = | |
113 StorageAdviser::recommend(StorageAdviser::SpeedCritical, kb, kb); | |
114 if (rec == StorageAdviser::UseMemory || | |
115 rec == StorageAdviser::PreferMemory) { | |
116 cacheMode = CodedAudioFileReader::CacheInMemory; | |
117 } | |
118 } | |
119 | |
120 CodedAudioFileReader::DecodeMode decodeMode = | |
121 (threading ? | |
122 CodedAudioFileReader::DecodeThreaded : | |
123 CodedAudioFileReader::DecodeAtOnce); | |
124 | |
101 // Try to construct a preferred reader based on the extension or | 125 // Try to construct a preferred reader based on the extension or |
102 // MIME type. | 126 // MIME type. |
127 | |
128 #define CHECK(reader) if (!reader->isOK()) { delete reader; reader = 0; } | |
103 | 129 |
104 if (WavFileReader::supports(source)) { | 130 if (WavFileReader::supports(source)) { |
105 | 131 |
106 reader = new WavFileReader(source); | 132 reader = new WavFileReader(source); |
107 | 133 |
108 sv_samplerate_t fileRate = reader->getSampleRate(); | 134 sv_samplerate_t fileRate = reader->getSampleRate(); |
109 | 135 |
110 if (reader->isOK() && | 136 if (reader->isOK() && |
111 (!reader->isQuicklySeekable() || | 137 (!reader->isQuicklySeekable() || |
112 normalised || | 138 normalised || |
139 (cacheMode == CodedAudioFileReader::CacheInMemory) || | |
113 (targetRate != 0 && fileRate != targetRate))) { | 140 (targetRate != 0 && fileRate != targetRate))) { |
114 | 141 |
115 SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", creating decoding reader" << endl; | 142 SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", in memory " << (cacheMode == CodedAudioFileReader::CacheInMemory) << ", creating decoding reader" << endl; |
116 | 143 |
117 delete reader; | 144 delete reader; |
118 reader = new DecodingWavFileReader | 145 reader = new DecodingWavFileReader |
119 (source, | 146 (source, |
120 threading ? | 147 decodeMode, cacheMode, |
121 DecodingWavFileReader::ResampleThreaded : | |
122 DecodingWavFileReader::ResampleAtOnce, | |
123 DecodingWavFileReader::CacheInTemporaryFile, | |
124 targetRate ? targetRate : fileRate, | 148 targetRate ? targetRate : fileRate, |
125 normalised, | 149 normalised, |
126 reporter); | 150 reporter); |
127 if (!reader->isOK()) { | 151 CHECK(reader); |
128 delete reader; | |
129 reader = 0; | |
130 } | |
131 } | 152 } |
132 } | 153 } |
133 | 154 |
134 #ifdef HAVE_OGGZ | 155 #ifdef HAVE_OGGZ |
135 #ifdef HAVE_FISHSOUND | 156 #ifdef HAVE_FISHSOUND |
136 if (!reader) { | 157 if (!reader && OggVorbisFileReader::supports(source)) { |
137 if (OggVorbisFileReader::supports(source)) { | 158 reader = new OggVorbisFileReader |
138 reader = new OggVorbisFileReader | 159 (source, decodeMode, cacheMode, targetRate, normalised, reporter); |
139 (source, | 160 CHECK(reader); |
140 threading ? | |
141 OggVorbisFileReader::DecodeThreaded : | |
142 OggVorbisFileReader::DecodeAtOnce, | |
143 OggVorbisFileReader::CacheInTemporaryFile, | |
144 targetRate, | |
145 normalised, | |
146 reporter); | |
147 if (!reader->isOK()) { | |
148 delete reader; | |
149 reader = 0; | |
150 } | |
151 } | |
152 } | 161 } |
153 #endif | 162 #endif |
154 #endif | 163 #endif |
155 | 164 |
156 #ifdef HAVE_MAD | 165 #ifdef HAVE_MAD |
157 if (!reader) { | 166 if (!reader && MP3FileReader::supports(source)) { |
158 if (MP3FileReader::supports(source)) { | 167 reader = new MP3FileReader |
159 reader = new MP3FileReader | 168 (source, decodeMode, cacheMode, targetRate, normalised, reporter); |
160 (source, | 169 CHECK(reader); |
161 threading ? | |
162 MP3FileReader::DecodeThreaded : | |
163 MP3FileReader::DecodeAtOnce, | |
164 MP3FileReader::CacheInTemporaryFile, | |
165 targetRate, | |
166 normalised, | |
167 reporter); | |
168 if (!reader->isOK()) { | |
169 delete reader; | |
170 reader = 0; | |
171 } | |
172 } | |
173 } | 170 } |
174 #endif | 171 #endif |
175 | 172 |
176 #ifdef HAVE_QUICKTIME | 173 #ifdef HAVE_QUICKTIME |
177 if (!reader) { | 174 if (!reader && QuickTimeFileReader::supports(source)) { |
178 if (QuickTimeFileReader::supports(source)) { | 175 reader = new QuickTimeFileReader |
179 reader = new QuickTimeFileReader | 176 (source, decodeMode, cacheMode, targetRate, normalised, reporter); |
180 (source, | 177 CHECK(reader); |
181 threading ? | |
182 QuickTimeFileReader::DecodeThreaded : | |
183 QuickTimeFileReader::DecodeAtOnce, | |
184 QuickTimeFileReader::CacheInTemporaryFile, | |
185 targetRate, | |
186 normalised, | |
187 reporter); | |
188 if (!reader->isOK()) { | |
189 delete reader; | |
190 reader = 0; | |
191 } | |
192 } | |
193 } | 178 } |
194 #endif | 179 #endif |
195 | 180 |
196 #ifdef HAVE_COREAUDIO | 181 #ifdef HAVE_COREAUDIO |
197 if (!reader) { | 182 if (!reader && CoreAudioFileReader::supports(source)) { |
198 if (CoreAudioFileReader::supports(source)) { | 183 reader = new CoreAudioFileReader |
199 reader = new CoreAudioFileReader | 184 (source, decodeMode, cacheMode, targetRate, normalised, reporter); |
200 (source, | 185 CHECK(reader); |
201 threading ? | 186 } |
202 CoreAudioFileReader::DecodeThreaded : | 187 #endif |
203 CoreAudioFileReader::DecodeAtOnce, | 188 |
204 CoreAudioFileReader::CacheInTemporaryFile, | 189 if (reader) { |
205 targetRate, | 190 // The happy case: a reader recognised the file extension & |
206 normalised, | 191 // succeeded in opening the file |
207 reporter); | 192 return reader; |
208 if (!reader->isOK()) { | 193 } |
209 delete reader; | 194 |
210 reader = 0; | |
211 } | |
212 } | |
213 } | |
214 #endif | |
215 | |
216 | |
217 // If none of the readers claimed to support this file extension, | 195 // If none of the readers claimed to support this file extension, |
218 // perhaps the extension is missing or misleading. Try again, | 196 // perhaps the extension is missing or misleading. Try again, |
219 // ignoring it. We have to be confident that the reader won't | 197 // ignoring it. We have to be confident that the reader won't |
220 // open just any old text file or whatever and pretend it's | 198 // open just any old text file or whatever and pretend it's |
221 // succeeded | 199 // succeeded |
222 | 200 |
223 if (!reader) { | 201 reader = new WavFileReader(source); |
224 | 202 |
225 reader = new WavFileReader(source); | 203 sv_samplerate_t fileRate = reader->getSampleRate(); |
226 | 204 |
227 sv_samplerate_t fileRate = reader->getSampleRate(); | 205 if (reader->isOK() && |
228 | 206 (!reader->isQuicklySeekable() || |
229 if (reader->isOK() && | 207 normalised || |
230 (!reader->isQuicklySeekable() || | 208 (cacheMode == CodedAudioFileReader::CacheInMemory) || |
231 normalised || | 209 (targetRate != 0 && fileRate != targetRate))) { |
232 (targetRate != 0 && fileRate != targetRate))) { | 210 |
233 | 211 SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", in memory " << (cacheMode == CodedAudioFileReader::CacheInMemory) << ", creating decoding reader" << endl; |
234 SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", creating decoding reader" << endl; | 212 |
235 | 213 delete reader; |
236 delete reader; | 214 reader = new DecodingWavFileReader |
237 reader = new DecodingWavFileReader | 215 (source, |
238 (source, | 216 decodeMode, cacheMode, |
239 threading ? | 217 targetRate ? targetRate : fileRate, |
240 DecodingWavFileReader::ResampleThreaded : | 218 normalised, |
241 DecodingWavFileReader::ResampleAtOnce, | 219 reporter); |
242 DecodingWavFileReader::CacheInTemporaryFile, | 220 } |
243 targetRate ? targetRate : fileRate, | 221 |
244 normalised, | 222 CHECK(reader); |
245 reporter); | |
246 } | |
247 | |
248 if (!reader->isOK()) { | |
249 delete reader; | |
250 reader = 0; | |
251 } | |
252 } | |
253 | 223 |
254 #ifdef HAVE_OGGZ | 224 #ifdef HAVE_OGGZ |
255 #ifdef HAVE_FISHSOUND | 225 #ifdef HAVE_FISHSOUND |
256 if (!reader) { | 226 if (!reader) { |
257 reader = new OggVorbisFileReader | 227 reader = new OggVorbisFileReader |
258 (source, | 228 (source, decodeMode, cacheMode, targetRate, normalised, reporter); |
259 threading ? | 229 CHECK(reader); |
260 OggVorbisFileReader::DecodeThreaded : | |
261 OggVorbisFileReader::DecodeAtOnce, | |
262 OggVorbisFileReader::CacheInTemporaryFile, | |
263 targetRate, | |
264 reporter); | |
265 | |
266 if (!reader->isOK()) { | |
267 delete reader; | |
268 reader = 0; | |
269 } | |
270 } | 230 } |
271 #endif | 231 #endif |
272 #endif | 232 #endif |
273 | 233 |
274 #ifdef HAVE_MAD | 234 #ifdef HAVE_MAD |
275 if (!reader) { | 235 if (!reader) { |
276 reader = new MP3FileReader | 236 reader = new MP3FileReader |
277 (source, | 237 (source, decodeMode, cacheMode, targetRate, normalised, reporter); |
278 threading ? | 238 CHECK(reader); |
279 MP3FileReader::DecodeThreaded : | |
280 MP3FileReader::DecodeAtOnce, | |
281 MP3FileReader::CacheInTemporaryFile, | |
282 targetRate, | |
283 reporter); | |
284 | |
285 if (!reader->isOK()) { | |
286 delete reader; | |
287 reader = 0; | |
288 } | |
289 } | 239 } |
290 #endif | 240 #endif |
291 | 241 |
292 #ifdef HAVE_QUICKTIME | 242 #ifdef HAVE_QUICKTIME |
293 if (!reader) { | 243 if (!reader) { |
294 reader = new QuickTimeFileReader | 244 reader = new QuickTimeFileReader |
295 (source, | 245 (source, decodeMode, cacheMode, targetRate, normalised, reporter); |
296 threading ? | 246 CHECK(reader); |
297 QuickTimeFileReader::DecodeThreaded : | |
298 QuickTimeFileReader::DecodeAtOnce, | |
299 QuickTimeFileReader::CacheInTemporaryFile, | |
300 targetRate, | |
301 reporter); | |
302 | |
303 if (!reader->isOK()) { | |
304 delete reader; | |
305 reader = 0; | |
306 } | |
307 } | 247 } |
308 #endif | 248 #endif |
309 | 249 |
310 #ifdef HAVE_COREAUDIO | 250 #ifdef HAVE_COREAUDIO |
311 if (!reader) { | 251 if (!reader) { |
312 reader = new CoreAudioFileReader | 252 reader = new CoreAudioFileReader |
313 (source, | 253 (source, decodeMode, cacheMode, targetRate, normalised, reporter); |
314 threading ? | 254 CHECK(reader); |
315 CoreAudioFileReader::DecodeThreaded : | 255 } |
316 CoreAudioFileReader::DecodeAtOnce, | 256 #endif |
317 CoreAudioFileReader::CacheInTemporaryFile, | 257 |
318 targetRate, | 258 if (!reader) { |
319 reporter); | 259 cerr << "AudioFileReaderFactory::Failed to create a reader for " |
320 | 260 << "url \"" << source.getLocation() |
321 if (!reader->isOK()) { | 261 << "\" (content type \"" |
322 delete reader; | 262 << source.getContentType() << "\")" << endl; |
323 reader = 0; | 263 return nullptr; |
324 } | 264 } |
325 } | 265 |
326 #endif | |
327 | |
328 if (reader) { | |
329 if (reader->isOK()) { | |
330 SVDEBUG << "AudioFileReaderFactory: Reader is OK" << endl; | |
331 return reader; | |
332 } | |
333 cerr << "AudioFileReaderFactory: Preferred reader for " | |
334 << "url \"" << source.getLocation() | |
335 << "\" (content type \"" | |
336 << source.getContentType() << "\") failed"; | |
337 | |
338 if (reader->getError() != "") { | |
339 cerr << ": \"" << reader->getError() << "\""; | |
340 } | |
341 cerr << endl; | |
342 delete reader; | |
343 reader = 0; | |
344 } | |
345 | |
346 cerr << "AudioFileReaderFactory: No reader" << endl; | |
347 return reader; | 266 return reader; |
348 } | 267 } |
349 | 268 |