Mercurial > hg > svcore
comparison data/fileio/AudioFileSizeEstimator.cpp @ 1527:710e6250a401 zoom
Merge from default branch
author | Chris Cannam |
---|---|
date | Mon, 17 Sep 2018 13:51:14 +0100 |
parents | aadfb395e933 |
children | 70e172e6cc59 f8e3dcbafb4d |
comparison
equal
deleted
inserted
replaced
1324:d4a28d1479a8 | 1527:710e6250a401 |
---|---|
16 | 16 |
17 #include "WavFileReader.h" | 17 #include "WavFileReader.h" |
18 | 18 |
19 #include <QFile> | 19 #include <QFile> |
20 | 20 |
21 //#define DEBUG_AUDIO_FILE_SIZE_ESTIMATOR 1 | 21 #include "base/Debug.h" |
22 | 22 |
23 sv_frame_t | 23 sv_frame_t |
24 AudioFileSizeEstimator::estimate(FileSource source, | 24 AudioFileSizeEstimator::estimate(FileSource source, |
25 sv_samplerate_t targetRate) | 25 sv_samplerate_t targetRate) |
26 { | 26 { |
27 sv_frame_t estimate = 0; | 27 sv_frame_t estimate = 0; |
28 | 28 |
29 SVDEBUG << "AudioFileSizeEstimator: Sample count estimate requested for file \"" | |
30 << source.getLocalFilename() << "\"" << endl; | |
31 | |
29 // Most of our file readers don't know the sample count until | 32 // Most of our file readers don't know the sample count until |
30 // after they've finished decoding. This is an exception: | 33 // after they've finished decoding. This is an exception: |
31 | 34 |
32 WavFileReader *reader = new WavFileReader(source); | 35 WavFileReader *reader = new WavFileReader(source); |
33 if (reader->isOK() && | 36 if (reader->isOK() && |
34 reader->getChannelCount() > 0 && | 37 reader->getChannelCount() > 0 && |
35 reader->getFrameCount() > 0) { | 38 reader->getFrameCount() > 0) { |
36 sv_frame_t samples = | 39 sv_frame_t samples = |
37 reader->getFrameCount() * reader->getChannelCount(); | 40 reader->getFrameCount() * reader->getChannelCount(); |
38 sv_samplerate_t rate = reader->getSampleRate(); | 41 sv_samplerate_t rate = reader->getSampleRate(); |
39 if (targetRate != 0.0 && targetRate != rate) { | 42 if (targetRate != 0.0 && targetRate != rate) { |
40 samples = sv_frame_t(double(samples) * targetRate / rate); | 43 samples = sv_frame_t(double(samples) * targetRate / rate); |
41 } | 44 } |
42 delete reader; | 45 SVDEBUG << "AudioFileSizeEstimator: WAV file reader accepts this file, reports " |
43 estimate = samples; | 46 << samples << " samples" << endl; |
47 estimate = samples; | |
48 } else { | |
49 SVDEBUG << "AudioFileSizeEstimator: WAV file reader doesn't like this file, " | |
50 << "estimating from file size and extension instead" << endl; | |
44 } | 51 } |
52 | |
53 delete reader; | |
54 reader = 0; | |
45 | 55 |
46 if (estimate == 0) { | 56 if (estimate == 0) { |
47 | 57 |
48 // The remainder just makes an estimate based on the file size | 58 // The remainder just makes an estimate based on the file size |
49 // and extension. We don't even know its sample rate at this | 59 // and extension. We don't even know its sample rate at this |
50 // point, so the following is a wild guess. | 60 // point, so the following is a wild guess. |
51 | 61 |
52 double rateRatio = 1.0; | 62 double rateRatio = 1.0; |
53 if (targetRate != 0.0) { | 63 if (targetRate != 0.0) { |
54 rateRatio = targetRate / 44100.0; | 64 rateRatio = targetRate / 44100.0; |
55 } | 65 } |
56 | 66 |
57 QString extension = source.getExtension(); | 67 QString extension = source.getExtension(); |
58 | 68 |
59 source.waitForData(); | 69 source.waitForData(); |
60 if (!source.isOK()) return 0; | 70 if (!source.isOK()) return 0; |
61 | 71 |
62 sv_frame_t sz = 0; | 72 sv_frame_t sz = 0; |
63 { | |
64 QFile f(source.getLocalFilename()); | |
65 if (f.open(QFile::ReadOnly)) { | |
66 #ifdef DEBUG_AUDIO_FILE_SIZE_ESTIMATOR | |
67 cerr << "opened file, size is " << f.size() << endl; | |
68 #endif | |
69 sz = f.size(); | |
70 f.close(); | |
71 } | |
72 } | |
73 | 73 |
74 if (extension == "ogg" || extension == "oga" || | 74 { |
75 extension == "m4a" || extension == "mp3" || | 75 QFile f(source.getLocalFilename()); |
76 extension == "wma") { | 76 if (f.open(QFile::ReadOnly)) { |
77 SVDEBUG << "AudioFileSizeEstimator: opened file, size is " | |
78 << f.size() << endl; | |
79 sz = f.size(); | |
80 f.close(); | |
81 } | |
82 } | |
77 | 83 |
78 // Usually a lossy file. Compression ratios can vary | 84 if (extension == "ogg" || extension == "oga" || |
79 // dramatically, but don't usually exceed about 20x compared | 85 extension == "m4a" || extension == "mp3" || |
80 // to 16-bit PCM (e.g. a 128kbps mp3 has 11x ratio over WAV at | 86 extension == "wma") { |
81 // 44.1kHz). We can estimate the number of samples to be file | |
82 // size x 20, divided by 2 as we're comparing with 16-bit PCM. | |
83 | 87 |
84 estimate = sv_frame_t(double(sz) * 10 * rateRatio); | 88 // Usually a lossy file. Compression ratios can vary |
85 } | 89 // dramatically, but don't usually exceed about 20x compared |
90 // to 16-bit PCM (e.g. a 128kbps mp3 has 11x ratio over WAV at | |
91 // 44.1kHz). We can estimate the number of samples to be file | |
92 // size x 20, divided by 2 as we're comparing with 16-bit PCM. | |
86 | 93 |
87 if (extension == "flac") { | 94 estimate = sv_frame_t(double(sz) * 10 * rateRatio); |
88 | 95 } |
89 // FLAC usually takes up a bit more than half the space of | |
90 // 16-bit PCM. So the number of 16-bit samples is roughly the | |
91 // same as the file size in bytes. As above, let's be | |
92 // conservative. | |
93 | 96 |
94 estimate = sv_frame_t(double(sz) * 1.2 * rateRatio); | 97 if (extension == "flac") { |
95 } | 98 |
99 // FLAC usually takes up a bit more than half the space of | |
100 // 16-bit PCM. So the number of 16-bit samples is roughly the | |
101 // same as the file size in bytes. As above, let's be | |
102 // conservative. | |
96 | 103 |
97 #ifdef DEBUG_AUDIO_FILE_SIZE_ESTIMATOR | 104 estimate = sv_frame_t(double(sz) * 1.2 * rateRatio); |
98 cerr << "AudioFileSizeEstimator: for extension " << extension << ", estimate = " << estimate << endl; | 105 } |
99 #endif | 106 |
107 SVDEBUG << "AudioFileSizeEstimator: for extension \"" | |
108 << extension << "\", estimate = " << estimate << " samples" << endl; | |
100 } | 109 } |
101 | |
102 #ifdef DEBUG_AUDIO_FILE_SIZE_ESTIMATOR | |
103 cerr << "estimate = " << estimate << endl; | |
104 #endif | |
105 | 110 |
106 return estimate; | 111 return estimate; |
107 } | 112 } |
108 | 113 |