annotate data/fileio/AudioFileSizeEstimator.cpp @ 1412:b7a9edee85e0 scale-ticks

Change loop to something that feels more correct, though it makes no difference to the tests here. More tests, one failing.
author Chris Cannam
date Thu, 04 May 2017 08:32:41 +0100
parents aadfb395e933
children 70e172e6cc59 f8e3dcbafb4d
rev   line source
Chris@1098 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@1098 2
Chris@1098 3 /*
Chris@1098 4 Sonic Visualiser
Chris@1098 5 An audio file viewer and annotation editor.
Chris@1098 6 Centre for Digital Music, Queen Mary, University of London.
Chris@1098 7
Chris@1098 8 This program is free software; you can redistribute it and/or
Chris@1098 9 modify it under the terms of the GNU General Public License as
Chris@1098 10 published by the Free Software Foundation; either version 2 of the
Chris@1098 11 License, or (at your option) any later version. See the file
Chris@1098 12 COPYING included with this distribution for more information.
Chris@1098 13 */
Chris@1098 14
Chris@1098 15 #include "AudioFileSizeEstimator.h"
Chris@1098 16
Chris@1098 17 #include "WavFileReader.h"
Chris@1098 18
Chris@1098 19 #include <QFile>
Chris@1098 20
Chris@1342 21 #include "base/Debug.h"
Chris@1104 22
Chris@1098 23 sv_frame_t
Chris@1098 24 AudioFileSizeEstimator::estimate(FileSource source,
Chris@1341 25 sv_samplerate_t targetRate)
Chris@1098 26 {
Chris@1098 27 sv_frame_t estimate = 0;
Chris@1098 28
Chris@1342 29 SVDEBUG << "AudioFileSizeEstimator: Sample count estimate requested for file \""
Chris@1342 30 << source.getLocalFilename() << "\"" << endl;
Chris@1342 31
Chris@1098 32 // Most of our file readers don't know the sample count until
Chris@1098 33 // after they've finished decoding. This is an exception:
Chris@1098 34
Chris@1098 35 WavFileReader *reader = new WavFileReader(source);
Chris@1098 36 if (reader->isOK() &&
Chris@1341 37 reader->getChannelCount() > 0 &&
Chris@1341 38 reader->getFrameCount() > 0) {
Chris@1341 39 sv_frame_t samples =
Chris@1341 40 reader->getFrameCount() * reader->getChannelCount();
Chris@1341 41 sv_samplerate_t rate = reader->getSampleRate();
Chris@1341 42 if (targetRate != 0.0 && targetRate != rate) {
Chris@1341 43 samples = sv_frame_t(double(samples) * targetRate / rate);
Chris@1341 44 }
Chris@1342 45 SVDEBUG << "AudioFileSizeEstimator: WAV file reader accepts this file, reports "
Chris@1342 46 << samples << " samples" << endl;
Chris@1341 47 estimate = samples;
Chris@1342 48 } else {
Chris@1342 49 SVDEBUG << "AudioFileSizeEstimator: WAV file reader doesn't like this file, "
Chris@1342 50 << "estimating from file size and extension instead" << endl;
Chris@1098 51 }
Chris@1098 52
Chris@1402 53 delete reader;
Chris@1402 54 reader = 0;
Chris@1402 55
Chris@1098 56 if (estimate == 0) {
Chris@1098 57
Chris@1341 58 // The remainder just makes an estimate based on the file size
Chris@1341 59 // and extension. We don't even know its sample rate at this
Chris@1341 60 // point, so the following is a wild guess.
Chris@1341 61
Chris@1341 62 double rateRatio = 1.0;
Chris@1341 63 if (targetRate != 0.0) {
Chris@1341 64 rateRatio = targetRate / 44100.0;
Chris@1341 65 }
Chris@1098 66
Chris@1341 67 QString extension = source.getExtension();
Chris@1098 68
Chris@1341 69 source.waitForData();
Chris@1341 70 if (!source.isOK()) return 0;
Chris@1098 71
Chris@1341 72 sv_frame_t sz = 0;
Chris@1342 73
Chris@1341 74 {
Chris@1341 75 QFile f(source.getLocalFilename());
Chris@1341 76 if (f.open(QFile::ReadOnly)) {
Chris@1342 77 SVDEBUG << "AudioFileSizeEstimator: opened file, size is "
Chris@1342 78 << f.size() << endl;
Chris@1341 79 sz = f.size();
Chris@1341 80 f.close();
Chris@1341 81 }
Chris@1341 82 }
Chris@1098 83
Chris@1341 84 if (extension == "ogg" || extension == "oga" ||
Chris@1341 85 extension == "m4a" || extension == "mp3" ||
Chris@1341 86 extension == "wma") {
Chris@1098 87
Chris@1341 88 // Usually a lossy file. Compression ratios can vary
Chris@1341 89 // dramatically, but don't usually exceed about 20x compared
Chris@1341 90 // to 16-bit PCM (e.g. a 128kbps mp3 has 11x ratio over WAV at
Chris@1341 91 // 44.1kHz). We can estimate the number of samples to be file
Chris@1341 92 // size x 20, divided by 2 as we're comparing with 16-bit PCM.
Chris@1098 93
Chris@1341 94 estimate = sv_frame_t(double(sz) * 10 * rateRatio);
Chris@1341 95 }
Chris@1098 96
Chris@1341 97 if (extension == "flac") {
Chris@1341 98
Chris@1341 99 // FLAC usually takes up a bit more than half the space of
Chris@1341 100 // 16-bit PCM. So the number of 16-bit samples is roughly the
Chris@1341 101 // same as the file size in bytes. As above, let's be
Chris@1341 102 // conservative.
Chris@1098 103
Chris@1341 104 estimate = sv_frame_t(double(sz) * 1.2 * rateRatio);
Chris@1341 105 }
Chris@1098 106
Chris@1342 107 SVDEBUG << "AudioFileSizeEstimator: for extension \""
Chris@1342 108 << extension << "\", estimate = " << estimate << " samples" << endl;
Chris@1098 109 }
Chris@1098 110
Chris@1098 111 return estimate;
Chris@1098 112 }
Chris@1098 113