annotate data/fileio/AudioFileSizeEstimator.cpp @ 1248:58dd6a6fe414 piper

Update to use listargs variant of Piper stuff (so that the plugin winnowing feature from the penultimate commit actually works)
author Chris Cannam
date Thu, 03 Nov 2016 15:38:17 +0000
parents 393134235fa0
children 513e4d67d8df
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@1104 21 //#define DEBUG_AUDIO_FILE_SIZE_ESTIMATOR 1
Chris@1104 22
Chris@1098 23 sv_frame_t
Chris@1098 24 AudioFileSizeEstimator::estimate(FileSource source,
Chris@1098 25 sv_samplerate_t targetRate)
Chris@1098 26 {
Chris@1098 27 sv_frame_t estimate = 0;
Chris@1098 28
Chris@1098 29 // Most of our file readers don't know the sample count until
Chris@1098 30 // after they've finished decoding. This is an exception:
Chris@1098 31
Chris@1098 32 WavFileReader *reader = new WavFileReader(source);
Chris@1098 33 if (reader->isOK() &&
Chris@1098 34 reader->getChannelCount() > 0 &&
Chris@1098 35 reader->getFrameCount() > 0) {
Chris@1098 36 sv_frame_t samples =
Chris@1098 37 reader->getFrameCount() * reader->getChannelCount();
Chris@1098 38 sv_samplerate_t rate = reader->getSampleRate();
Chris@1098 39 if (targetRate != 0.0 && targetRate != rate) {
Chris@1098 40 samples = sv_frame_t(double(samples) * targetRate / rate);
Chris@1098 41 }
Chris@1098 42 delete reader;
Chris@1098 43 estimate = samples;
Chris@1098 44 }
Chris@1098 45
Chris@1098 46 if (estimate == 0) {
Chris@1098 47
Chris@1098 48 // The remainder just makes an estimate based on the file size
Chris@1098 49 // and extension. We don't even know its sample rate at this
Chris@1098 50 // point, so the following is a wild guess.
Chris@1098 51
Chris@1098 52 double rateRatio = 1.0;
Chris@1098 53 if (targetRate != 0.0) {
Chris@1098 54 rateRatio = targetRate / 44100.0;
Chris@1098 55 }
Chris@1098 56
Chris@1098 57 QString extension = source.getExtension();
Chris@1098 58
Chris@1098 59 source.waitForData();
Chris@1098 60 if (!source.isOK()) return 0;
Chris@1098 61
Chris@1098 62 sv_frame_t sz = 0;
Chris@1098 63 {
Chris@1098 64 QFile f(source.getLocalFilename());
Chris@1098 65 if (f.open(QFile::ReadOnly)) {
Chris@1104 66 #ifdef DEBUG_AUDIO_FILE_SIZE_ESTIMATOR
Chris@1098 67 cerr << "opened file, size is " << f.size() << endl;
Chris@1104 68 #endif
Chris@1098 69 sz = f.size();
Chris@1098 70 f.close();
Chris@1098 71 }
Chris@1098 72 }
Chris@1098 73
Chris@1098 74 if (extension == "ogg" || extension == "oga" ||
Chris@1098 75 extension == "m4a" || extension == "mp3" ||
Chris@1098 76 extension == "wma") {
Chris@1098 77
Chris@1098 78 // Usually a lossy file. Compression ratios can vary
Chris@1098 79 // dramatically, but don't usually exceed about 20x compared
Chris@1098 80 // to 16-bit PCM (e.g. a 128kbps mp3 has 11x ratio over WAV at
Chris@1098 81 // 44.1kHz). We can estimate the number of samples to be file
Chris@1098 82 // size x 20, divided by 2 as we're comparing with 16-bit PCM.
Chris@1098 83
Chris@1098 84 estimate = sv_frame_t(double(sz) * 10 * rateRatio);
Chris@1098 85 }
Chris@1098 86
Chris@1098 87 if (extension == "flac") {
Chris@1098 88
Chris@1098 89 // FLAC usually takes up a bit more than half the space of
Chris@1098 90 // 16-bit PCM. So the number of 16-bit samples is roughly the
Chris@1098 91 // same as the file size in bytes. As above, let's be
Chris@1098 92 // conservative.
Chris@1098 93
Chris@1098 94 estimate = sv_frame_t(double(sz) * 1.2 * rateRatio);
Chris@1098 95 }
Chris@1098 96
Chris@1104 97 #ifdef DEBUG_AUDIO_FILE_SIZE_ESTIMATOR
Chris@1098 98 cerr << "AudioFileSizeEstimator: for extension " << extension << ", estimate = " << estimate << endl;
Chris@1104 99 #endif
Chris@1098 100 }
Chris@1098 101
Chris@1104 102 #ifdef DEBUG_AUDIO_FILE_SIZE_ESTIMATOR
Chris@1098 103 cerr << "estimate = " << estimate << endl;
Chris@1104 104 #endif
Chris@1098 105
Chris@1098 106 return estimate;
Chris@1098 107 }
Chris@1098 108