Mercurial > hg > svcore
comparison data/fileio/WavFileReader.cpp @ 1513:75d92155fa20 import-audio-data
Add normalisation option
author | Chris Cannam |
---|---|
date | Fri, 07 Sep 2018 16:13:21 +0100 |
parents | 330bcc92507d |
children | 954d0cf29ca7 |
comparison
equal
deleted
inserted
replaced
1512:c9c2aa17439a | 1513:75d92155fa20 |
---|---|
23 #include <QMutexLocker> | 23 #include <QMutexLocker> |
24 #include <QFileInfo> | 24 #include <QFileInfo> |
25 | 25 |
26 using namespace std; | 26 using namespace std; |
27 | 27 |
28 WavFileReader::WavFileReader(FileSource source, bool fileUpdating) : | 28 WavFileReader::WavFileReader(FileSource source, |
29 bool fileUpdating, | |
30 bool normalise) : | |
29 m_file(0), | 31 m_file(0), |
30 m_source(source), | 32 m_source(source), |
31 m_path(source.getLocalFilename()), | 33 m_path(source.getLocalFilename()), |
32 m_seekable(false), | 34 m_seekable(false), |
33 m_lastStart(0), | 35 m_lastStart(0), |
34 m_lastCount(0), | 36 m_lastCount(0), |
37 m_normalise(normalise), | |
38 m_max(0.f), | |
35 m_updating(fileUpdating) | 39 m_updating(fileUpdating) |
36 { | 40 { |
37 m_frameCount = 0; | 41 m_frameCount = 0; |
38 m_channelCount = 0; | 42 m_channelCount = 0; |
39 m_sampleRate = 0; | 43 m_sampleRate = 0; |
85 // non-seekable. We know that certain common file types | 89 // non-seekable. We know that certain common file types |
86 // are definitely seekable so, again cautiously, identify | 90 // are definitely seekable so, again cautiously, identify |
87 // and mark those (basically only non-adaptive WAVs). | 91 // and mark those (basically only non-adaptive WAVs). |
88 m_seekable = true; | 92 m_seekable = true; |
89 } | 93 } |
90 } | 94 |
91 | 95 if (m_normalise && !m_updating) { |
92 SVDEBUG << "WavFileReader: Filename " << m_path << ", frame count " << m_frameCount << ", channel count " << m_channelCount << ", sample rate " << m_sampleRate << ", format " << m_fileInfo.format << ", seekable " << m_fileInfo.seekable << " adjusted to " << m_seekable << endl; | 96 m_max = getMax(); |
97 } | |
98 } | |
99 | |
100 SVDEBUG << "WavFileReader: Filename " << m_path << ", frame count " << m_frameCount << ", channel count " << m_channelCount << ", sample rate " << m_sampleRate << ", format " << m_fileInfo.format << ", seekable " << m_fileInfo.seekable << " adjusted to " << m_seekable << ", normalise " << m_normalise << endl; | |
93 } | 101 } |
94 | 102 |
95 WavFileReader::~WavFileReader() | 103 WavFileReader::~WavFileReader() |
96 { | 104 { |
97 if (m_file) sf_close(m_file); | 105 if (m_file) sf_close(m_file); |
134 void | 142 void |
135 WavFileReader::updateDone() | 143 WavFileReader::updateDone() |
136 { | 144 { |
137 updateFrameCount(); | 145 updateFrameCount(); |
138 m_updating = false; | 146 m_updating = false; |
147 if (m_normalise) { | |
148 m_max = getMax(); | |
149 } | |
139 } | 150 } |
140 | 151 |
141 floatvec_t | 152 floatvec_t |
142 WavFileReader::getInterleavedFrames(sv_frame_t start, sv_frame_t count) const | 153 WavFileReader::getInterleavedFrames(sv_frame_t start, sv_frame_t count) const |
154 { | |
155 floatvec_t frames = getInterleavedFramesUnnormalised(start, count); | |
156 | |
157 if (!m_normalise || m_max == 0.f) { | |
158 return frames; | |
159 } | |
160 | |
161 for (int i = 0; in_range_for(frames, i); ++i) { | |
162 frames[i] /= m_max; | |
163 } | |
164 | |
165 return frames; | |
166 } | |
167 | |
168 floatvec_t | |
169 WavFileReader::getInterleavedFramesUnnormalised(sv_frame_t start, | |
170 sv_frame_t count) const | |
143 { | 171 { |
144 static HitCount lastRead("WavFileReader: last read"); | 172 static HitCount lastRead("WavFileReader: last read"); |
145 | 173 |
146 if (count == 0) return {}; | 174 if (count == 0) return {}; |
147 | 175 |
196 return {}; | 224 return {}; |
197 } | 225 } |
198 | 226 |
199 m_buffer = data; | 227 m_buffer = data; |
200 return data; | 228 return data; |
229 } | |
230 | |
231 float | |
232 WavFileReader::getMax() const | |
233 { | |
234 if (!m_file || !m_channelCount) { | |
235 return 0.f; | |
236 } | |
237 | |
238 // First try for a PEAK chunk | |
239 | |
240 double sfpeak = 0.0; | |
241 if (sf_command(m_file, SFC_GET_SIGNAL_MAX, &sfpeak, sizeof(sfpeak)) | |
242 == SF_TRUE) { | |
243 SVDEBUG << "File has a PEAK chunk reporting max level " << sfpeak | |
244 << endl; | |
245 return float(fabs(sfpeak)); | |
246 } | |
247 | |
248 // Failing that, read all the samples | |
249 | |
250 float peak = 0.f; | |
251 sv_frame_t ix = 0, chunk = 65536; | |
252 | |
253 while (ix < m_frameCount) { | |
254 auto frames = getInterleavedFrames(ix, chunk); | |
255 for (float x: frames) { | |
256 float level = fabsf(x); | |
257 if (level > peak) { | |
258 peak = level; | |
259 } | |
260 } | |
261 ix += chunk; | |
262 } | |
263 | |
264 SVDEBUG << "Measured file peak max level as " << peak << endl; | |
265 return peak; | |
201 } | 266 } |
202 | 267 |
203 void | 268 void |
204 WavFileReader::getSupportedExtensions(set<QString> &extensions) | 269 WavFileReader::getSupportedExtensions(set<QString> &extensions) |
205 { | 270 { |