comparison data/fileio/MP3FileReader.cpp @ 297:c022976d18e8

* Merge from sv-match-alignment branch (excluding alignment-specific document). - add aggregate wave model (not yet complete enough to be added as a true model in a layer, but there's potential) - add play solo mode - add alignment model -- unused in plain SV - fix two plugin leaks - add m3u playlist support (opens all files at once, potentially hazardous) - fix retrieval of pre-encoded URLs - add ability to resample audio files on import, so as to match rates with other files previously loaded; add preference for same - add preliminary support in transform code for range and rate of transform input - reorganise preferences dialog, move dark-background option to preferences, add option for temporary directory location
author Chris Cannam
date Fri, 28 Sep 2007 13:56:38 +0000
parents 92e8dbde73cd
children 3a6725f285d6
comparison
equal deleted inserted replaced
296:2b6c99b607f1 297:c022976d18e8
32 32
33 #include <QApplication> 33 #include <QApplication>
34 #include <QFileInfo> 34 #include <QFileInfo>
35 #include <QProgressDialog> 35 #include <QProgressDialog>
36 36
37 MP3FileReader::MP3FileReader(QString path, DecodeMode decodeMode, CacheMode mode) : 37 MP3FileReader::MP3FileReader(QString path, DecodeMode decodeMode,
38 CodedAudioFileReader(mode), 38 CacheMode mode, size_t targetRate) :
39 CodedAudioFileReader(mode, targetRate),
39 m_path(path), 40 m_path(path),
40 m_decodeThread(0) 41 m_decodeThread(0)
41 { 42 {
42 m_frameCount = 0;
43 m_channelCount = 0; 43 m_channelCount = 0;
44 m_sampleRate = 0; 44 m_fileRate = 0;
45 m_fileSize = 0; 45 m_fileSize = 0;
46 m_bitrateNum = 0; 46 m_bitrateNum = 0;
47 m_bitrateDenom = 0; 47 m_bitrateDenom = 0;
48 m_frameCount = 0;
49 m_cancelled = false; 48 m_cancelled = false;
50 m_completion = 0; 49 m_completion = 0;
51 m_done = false; 50 m_done = false;
52 m_progress = 0; 51 m_progress = 0;
53 52
68 m_error = QString("Failed to open file %1 for reading.").arg(path); 67 m_error = QString("Failed to open file %1 for reading.").arg(path);
69 return; 68 return;
70 } 69 }
71 70
72 m_filebuffer = 0; 71 m_filebuffer = 0;
72 m_samplebuffer = 0;
73 m_samplebuffersize = 0;
73 74
74 try { 75 try {
75 m_filebuffer = new unsigned char[m_fileSize]; 76 m_filebuffer = new unsigned char[m_fileSize];
76 } catch (...) { 77 } catch (...) {
77 m_error = QString("Out of memory"); 78 m_error = QString("Out of memory");
224 m_reader->m_error = QString("Failed to decode file %1.").arg(m_reader->m_path); 225 m_reader->m_error = QString("Failed to decode file %1.").arg(m_reader->m_path);
225 } 226 }
226 227
227 delete[] m_reader->m_filebuffer; 228 delete[] m_reader->m_filebuffer;
228 m_reader->m_filebuffer = 0; 229 m_reader->m_filebuffer = 0;
229 230
231 if (m_reader->m_samplebuffer) {
232 for (size_t c = 0; c < m_reader->m_channelCount; ++c) {
233 delete[] m_reader->m_samplebuffer[c];
234 }
235 delete[] m_reader->m_samplebuffer;
236 m_reader->m_samplebuffer = 0;
237 }
238
230 if (m_reader->isDecodeCacheInitialised()) m_reader->finishDecodeCache(); 239 if (m_reader->isDecodeCacheInitialised()) m_reader->finishDecodeCache();
231 240
232 m_reader->m_done = true; 241 m_reader->m_done = true;
233 m_reader->m_completion = 100; 242 m_reader->m_completion = 100;
243
244 m_reader->endSerialised();
234 } 245 }
235 246
236 bool 247 bool
237 MP3FileReader::decode(void *mm, size_t sz) 248 MP3FileReader::decode(void *mm, size_t sz)
238 { 249 {
285 } 296 }
286 297
287 if (frames < 1) return MAD_FLOW_CONTINUE; 298 if (frames < 1) return MAD_FLOW_CONTINUE;
288 299
289 if (m_channelCount == 0) { 300 if (m_channelCount == 0) {
301
302 m_fileRate = pcm->samplerate;
290 m_channelCount = channels; 303 m_channelCount = channels;
291 m_sampleRate = pcm->samplerate; 304
305 initialiseDecodeCache();
306
307 if (m_cacheMode == CacheInTemporaryFile) {
308 m_completion = 1;
309 std::cerr << "MP3FileReader::accept: channel count " << m_channelCount << ", file rate " << m_fileRate << ", about to start serialised section" << std::endl;
310 startSerialised("MP3FileReader::Decode");
311 }
292 } 312 }
293 313
294 if (m_bitrateDenom > 0) { 314 if (m_bitrateDenom > 0) {
295 double bitrate = m_bitrateNum / m_bitrateDenom; 315 double bitrate = m_bitrateNum / m_bitrateDenom;
296 double duration = double(m_fileSize * 8) / bitrate; 316 double duration = double(m_fileSize * 8) / bitrate;
313 } 333 }
314 } 334 }
315 335
316 if (m_cancelled) return MAD_FLOW_STOP; 336 if (m_cancelled) return MAD_FLOW_STOP;
317 337
318 m_frameCount += frames;
319
320 if (!isDecodeCacheInitialised()) { 338 if (!isDecodeCacheInitialised()) {
321 initialiseDecodeCache(); 339 initialiseDecodeCache();
322 } 340 }
323 341
324 for (int i = 0; i < frames; ++i) { 342 if (m_samplebuffersize < frames) {
325 343 if (!m_samplebuffer) {
326 for (int ch = 0; ch < channels; ++ch) { 344 m_samplebuffer = new float *[channels];
345 for (int c = 0; c < channels; ++c) {
346 m_samplebuffer[c] = 0;
347 }
348 }
349 for (int c = 0; c < channels; ++c) {
350 delete[] m_samplebuffer[c];
351 m_samplebuffer[c] = new float[frames];
352 }
353 m_samplebuffersize = frames;
354 }
355
356 int activeChannels = int(sizeof(pcm->samples) / sizeof(pcm->samples[0]));
357
358 for (int ch = 0; ch < channels; ++ch) {
359
360 for (int i = 0; i < frames; ++i) {
361
327 mad_fixed_t sample = 0; 362 mad_fixed_t sample = 0;
328 if (ch < int(sizeof(pcm->samples) / sizeof(pcm->samples[0]))) { 363 if (ch < activeChannels) {
329 sample = pcm->samples[ch][i]; 364 sample = pcm->samples[ch][i];
330 } 365 }
331 float fsample = float(sample) / float(MAD_F_ONE); 366 float fsample = float(sample) / float(MAD_F_ONE);
332 addSampleToDecodeCache(fsample); 367
368 m_samplebuffer[ch][i] = fsample;
333 } 369 }
334 370 }
335 if (! (i & 0xffff)) { 371
336 // periodically munlock to ensure we don't exhaust real memory 372 addSamplesToDecodeCache(m_samplebuffer, frames);
337 // if running with memory locked down
338 MUNLOCK_SAMPLEBLOCK(m_data);
339 }
340 }
341
342 if (frames > 0) {
343 MUNLOCK_SAMPLEBLOCK(m_data);
344 }
345 373
346 return MAD_FLOW_CONTINUE; 374 return MAD_FLOW_CONTINUE;
347 } 375 }
348 376
349 enum mad_flow 377 enum mad_flow