comparison data/model/WaveFileModel.cpp @ 936:0c1d6de8f44b

Merge from branch warnfix_no_size_t
author Chris Cannam
date Wed, 18 Jun 2014 13:51:16 +0100
parents d03b3d956358
children 6d2ece0fe356
comparison
equal deleted inserted replaced
917:49618f39ff09 936:0c1d6de8f44b
18 #include "fileio/AudioFileReader.h" 18 #include "fileio/AudioFileReader.h"
19 #include "fileio/AudioFileReaderFactory.h" 19 #include "fileio/AudioFileReaderFactory.h"
20 20
21 #include "system/System.h" 21 #include "system/System.h"
22 22
23 #include "base/Preferences.h"
24
23 #include <QFileInfo> 25 #include <QFileInfo>
24 #include <QTextStream> 26 #include <QTextStream>
25 27
26 #include <iostream> 28 #include <iostream>
27 #include <unistd.h> 29 #include <unistd.h>
33 //#define DEBUG_WAVE_FILE_MODEL 1 35 //#define DEBUG_WAVE_FILE_MODEL 1
34 36
35 PowerOfSqrtTwoZoomConstraint 37 PowerOfSqrtTwoZoomConstraint
36 WaveFileModel::m_zoomConstraint; 38 WaveFileModel::m_zoomConstraint;
37 39
38 WaveFileModel::WaveFileModel(FileSource source, size_t targetRate) : 40 WaveFileModel::WaveFileModel(FileSource source, int targetRate) :
39 m_source(source), 41 m_source(source),
40 m_path(source.getLocation()), 42 m_path(source.getLocation()),
41 m_myReader(true), 43 m_myReader(true),
42 m_startFrame(0), 44 m_startFrame(0),
43 m_fillThread(0), 45 m_fillThread(0),
47 m_lastDirectReadStart(0), 49 m_lastDirectReadStart(0),
48 m_lastDirectReadCount(0) 50 m_lastDirectReadCount(0)
49 { 51 {
50 m_source.waitForData(); 52 m_source.waitForData();
51 if (m_source.isOK()) { 53 if (m_source.isOK()) {
54 bool normalise = Preferences::getInstance()->getNormaliseAudio();
52 m_reader = AudioFileReaderFactory::createThreadingReader 55 m_reader = AudioFileReaderFactory::createThreadingReader
53 (m_source, targetRate); 56 (m_source, targetRate, normalise);
54 if (m_reader) { 57 if (m_reader) {
55 SVDEBUG << "WaveFileModel::WaveFileModel: reader rate: " 58 SVDEBUG << "WaveFileModel::WaveFileModel: reader rate: "
56 << m_reader->getSampleRate() << endl; 59 << m_reader->getSampleRate() << endl;
57 } 60 }
58 } 61 }
124 { 127 {
125 WaveFileModel *model = new WaveFileModel(m_source); 128 WaveFileModel *model = new WaveFileModel(m_source);
126 return model; 129 return model;
127 } 130 }
128 131
129 size_t 132 int
130 WaveFileModel::getFrameCount() const 133 WaveFileModel::getFrameCount() const
131 { 134 {
132 if (!m_reader) return 0; 135 if (!m_reader) return 0;
133 return m_reader->getFrameCount(); 136 return m_reader->getFrameCount();
134 } 137 }
135 138
136 size_t 139 int
137 WaveFileModel::getChannelCount() const 140 WaveFileModel::getChannelCount() const
138 { 141 {
139 if (!m_reader) return 0; 142 if (!m_reader) return 0;
140 return m_reader->getChannelCount(); 143 return m_reader->getChannelCount();
141 } 144 }
142 145
143 size_t 146 int
144 WaveFileModel::getSampleRate() const 147 WaveFileModel::getSampleRate() const
145 { 148 {
146 if (!m_reader) return 0; 149 if (!m_reader) return 0;
147 return m_reader->getSampleRate(); 150 return m_reader->getSampleRate();
148 } 151 }
149 152
150 size_t 153 int
151 WaveFileModel::getNativeRate() const 154 WaveFileModel::getNativeRate() const
152 { 155 {
153 if (!m_reader) return 0; 156 if (!m_reader) return 0;
154 size_t rate = m_reader->getNativeRate(); 157 int rate = m_reader->getNativeRate();
155 if (rate == 0) rate = getSampleRate(); 158 if (rate == 0) rate = getSampleRate();
156 return rate; 159 return rate;
157 } 160 }
158 161
159 QString 162 QString
177 { 180 {
178 if (m_reader) return m_reader->getLocation(); 181 if (m_reader) return m_reader->getLocation();
179 return ""; 182 return "";
180 } 183 }
181 184
182 size_t 185 int
183 WaveFileModel::getData(int channel, size_t start, size_t count, 186 WaveFileModel::getData(int channel, int start, int count,
184 float *buffer) const 187 float *buffer) const
185 { 188 {
186 // Always read these directly from the file. 189 // Always read these directly from the file.
187 // This is used for e.g. audio playback. 190 // This is used for e.g. audio playback.
188 // Could be much more efficient (although compiler optimisation will help) 191 // Could be much more efficient (although compiler optimisation will help)
192 #endif 195 #endif
193 196
194 if (start >= m_startFrame) { 197 if (start >= m_startFrame) {
195 start -= m_startFrame; 198 start -= m_startFrame;
196 } else { 199 } else {
197 for (size_t i = 0; i < count; ++i) buffer[i] = 0.f; 200 for (int i = 0; i < count; ++i) buffer[i] = 0.f;
198 if (count <= m_startFrame - start) { 201 if (count <= m_startFrame - start) {
199 return 0; 202 return 0;
200 } else { 203 } else {
201 count -= (m_startFrame - start); 204 count -= (m_startFrame - start);
202 start = 0; 205 start = 0;
203 } 206 }
204 } 207 }
205 208
206 if (!m_reader || !m_reader->isOK() || count == 0) { 209 if (!m_reader || !m_reader->isOK() || count == 0) {
207 for (size_t i = 0; i < count; ++i) buffer[i] = 0.f; 210 for (int i = 0; i < count; ++i) buffer[i] = 0.f;
208 return 0; 211 return 0;
209 } 212 }
210 213
211 #ifdef DEBUG_WAVE_FILE_MODEL 214 #ifdef DEBUG_WAVE_FILE_MODEL
212 // SVDEBUG << "WaveFileModel::getValues(" << channel << ", " 215 // SVDEBUG << "WaveFileModel::getValues(" << channel << ", "
216 int channels = getChannelCount(); 219 int channels = getChannelCount();
217 220
218 SampleBlock frames(count * channels); 221 SampleBlock frames(count * channels);
219 m_reader->getInterleavedFrames(start, count, frames); 222 m_reader->getInterleavedFrames(start, count, frames);
220 223
221 size_t i = 0; 224 int i = 0;
222 225
223 int ch0 = channel, ch1 = channel; 226 int ch0 = channel, ch1 = channel;
224 if (channel == -1) { 227 if (channel == -1) {
225 ch0 = 0; 228 ch0 = 0;
226 ch1 = channels - 1; 229 ch1 = channels - 1;
230 233
231 buffer[i] = 0.0; 234 buffer[i] = 0.0;
232 235
233 for (int ch = ch0; ch <= ch1; ++ch) { 236 for (int ch = ch0; ch <= ch1; ++ch) {
234 237
235 size_t index = i * channels + ch; 238 int index = i * channels + ch;
236 if (index >= frames.size()) break; 239 if (index >= (int)frames.size()) break;
237 240
238 float sample = frames[index]; 241 float sample = frames[index];
239 buffer[i] += sample; 242 buffer[i] += sample;
240 } 243 }
241 244
243 } 246 }
244 247
245 return i; 248 return i;
246 } 249 }
247 250
248 size_t 251 int
249 WaveFileModel::getData(int channel, size_t start, size_t count, 252 WaveFileModel::getData(int channel, int start, int count,
250 double *buffer) const 253 double *buffer) const
251 { 254 {
252 #ifdef DEBUG_WAVE_FILE_MODEL 255 #ifdef DEBUG_WAVE_FILE_MODEL
253 cout << "WaveFileModel::getData(double)[" << this << "]: " << channel << ", " << start << ", " << count << ", " << buffer << endl; 256 cout << "WaveFileModel::getData(double)[" << this << "]: " << channel << ", " << start << ", " << count << ", " << buffer << endl;
254 #endif 257 #endif
255 258
256 if (start > m_startFrame) { 259 if (start > m_startFrame) {
257 start -= m_startFrame; 260 start -= m_startFrame;
258 } else { 261 } else {
259 for (size_t i = 0; i < count; ++i) buffer[i] = 0.0; 262 for (int i = 0; i < count; ++i) buffer[i] = 0.0;
260 if (count <= m_startFrame - start) { 263 if (count <= m_startFrame - start) {
261 return 0; 264 return 0;
262 } else { 265 } else {
263 count -= (m_startFrame - start); 266 count -= (m_startFrame - start);
264 start = 0; 267 start = 0;
265 } 268 }
266 } 269 }
267 270
268 if (!m_reader || !m_reader->isOK() || count == 0) { 271 if (!m_reader || !m_reader->isOK() || count == 0) {
269 for (size_t i = 0; i < count; ++i) buffer[i] = 0.0; 272 for (int i = 0; i < count; ++i) buffer[i] = 0.0;
270 return 0; 273 return 0;
271 } 274 }
272 275
273 int channels = getChannelCount(); 276 int channels = getChannelCount();
274 277
275 SampleBlock frames(count * channels); 278 SampleBlock frames(count * channels);
276 m_reader->getInterleavedFrames(start, count, frames); 279 m_reader->getInterleavedFrames(start, count, frames);
277 280
278 size_t i = 0; 281 int i = 0;
279 282
280 int ch0 = channel, ch1 = channel; 283 int ch0 = channel, ch1 = channel;
281 if (channel == -1) { 284 if (channel == -1) {
282 ch0 = 0; 285 ch0 = 0;
283 ch1 = channels - 1; 286 ch1 = channels - 1;
287 290
288 buffer[i] = 0.0; 291 buffer[i] = 0.0;
289 292
290 for (int ch = ch0; ch <= ch1; ++ch) { 293 for (int ch = ch0; ch <= ch1; ++ch) {
291 294
292 size_t index = i * channels + ch; 295 int index = i * channels + ch;
293 if (index >= frames.size()) break; 296 if (index >= (int)frames.size()) break;
294 297
295 float sample = frames[index]; 298 float sample = frames[index];
296 buffer[i] += sample; 299 buffer[i] += sample;
297 } 300 }
298 301
300 } 303 }
301 304
302 return i; 305 return i;
303 } 306 }
304 307
305 size_t 308 int
306 WaveFileModel::getData(size_t fromchannel, size_t tochannel, 309 WaveFileModel::getData(int fromchannel, int tochannel,
307 size_t start, size_t count, 310 int start, int count,
308 float **buffer) const 311 float **buffer) const
309 { 312 {
310 #ifdef DEBUG_WAVE_FILE_MODEL 313 #ifdef DEBUG_WAVE_FILE_MODEL
311 cout << "WaveFileModel::getData[" << this << "]: " << fromchannel << "," << tochannel << ", " << start << ", " << count << ", " << buffer << endl; 314 cout << "WaveFileModel::getData[" << this << "]: " << fromchannel << "," << tochannel << ", " << start << ", " << count << ", " << buffer << endl;
312 #endif 315 #endif
313 316
314 size_t channels = getChannelCount(); 317 int channels = getChannelCount();
315 318
316 if (fromchannel > tochannel) { 319 if (fromchannel > tochannel) {
317 cerr << "ERROR: WaveFileModel::getData: fromchannel (" 320 cerr << "ERROR: WaveFileModel::getData: fromchannel ("
318 << fromchannel << ") > tochannel (" << tochannel << ")" 321 << fromchannel << ") > tochannel (" << tochannel << ")"
319 << endl; 322 << endl;
329 332
330 if (fromchannel == tochannel) { 333 if (fromchannel == tochannel) {
331 return getData(fromchannel, start, count, buffer[0]); 334 return getData(fromchannel, start, count, buffer[0]);
332 } 335 }
333 336
334 size_t reqchannels = (tochannel - fromchannel) + 1; 337 int reqchannels = (tochannel - fromchannel) + 1;
335 338
336 // Always read these directly from the file. 339 // Always read these directly from the file.
337 // This is used for e.g. audio playback. 340 // This is used for e.g. audio playback.
338 // Could be much more efficient (although compiler optimisation will help) 341 // Could be much more efficient (although compiler optimisation will help)
339 342
340 if (start >= m_startFrame) { 343 if (start >= m_startFrame) {
341 start -= m_startFrame; 344 start -= m_startFrame;
342 } else { 345 } else {
343 for (size_t c = 0; c < reqchannels; ++c) { 346 for (int c = 0; c < reqchannels; ++c) {
344 for (size_t i = 0; i < count; ++i) buffer[c][i] = 0.f; 347 for (int i = 0; i < count; ++i) buffer[c][i] = 0.f;
345 } 348 }
346 if (count <= m_startFrame - start) { 349 if (count <= m_startFrame - start) {
347 return 0; 350 return 0;
348 } else { 351 } else {
349 count -= (m_startFrame - start); 352 count -= (m_startFrame - start);
350 start = 0; 353 start = 0;
351 } 354 }
352 } 355 }
353 356
354 if (!m_reader || !m_reader->isOK() || count == 0) { 357 if (!m_reader || !m_reader->isOK() || count == 0) {
355 for (size_t c = 0; c < reqchannels; ++c) { 358 for (int c = 0; c < reqchannels; ++c) {
356 for (size_t i = 0; i < count; ++i) buffer[c][i] = 0.f; 359 for (int i = 0; i < count; ++i) buffer[c][i] = 0.f;
357 } 360 }
358 return 0; 361 return 0;
359 } 362 }
360 363
361 SampleBlock frames(count * channels); 364 SampleBlock frames(count * channels);
362 m_reader->getInterleavedFrames(start, count, frames); 365 m_reader->getInterleavedFrames(start, count, frames);
363 366
364 size_t i = 0; 367 int i = 0;
365 368
366 int ch0 = fromchannel, ch1 = tochannel; 369 int index = 0, available = frames.size();
367
368 size_t index = 0, available = frames.size();
369 370
370 while (i < count) { 371 while (i < count) {
371 372
372 if (index >= available) break; 373 if (index >= available) break;
373 374
374 size_t destc = 0; 375 int destc = 0;
375 376
376 for (size_t c = 0; c < channels; ++c) { 377 for (int c = 0; c < channels; ++c) {
377 378
378 if (c >= fromchannel && c <= tochannel) { 379 if (c >= fromchannel && c <= tochannel) {
379 buffer[destc][i] = frames[index]; 380 buffer[destc][i] = frames[index];
380 ++destc; 381 ++destc;
381 } 382 }
387 } 388 }
388 389
389 return i; 390 return i;
390 } 391 }
391 392
392 size_t 393 int
393 WaveFileModel::getSummaryBlockSize(size_t desired) const 394 WaveFileModel::getSummaryBlockSize(int desired) const
394 { 395 {
395 int cacheType = 0; 396 int cacheType = 0;
396 int power = m_zoomConstraint.getMinCachePower(); 397 int power = m_zoomConstraint.getMinCachePower();
397 size_t roundedBlockSize = m_zoomConstraint.getNearestBlockSize 398 int roundedBlockSize = m_zoomConstraint.getNearestBlockSize
398 (desired, cacheType, power, ZoomConstraint::RoundDown); 399 (desired, cacheType, power, ZoomConstraint::RoundDown);
399 if (cacheType != 0 && cacheType != 1) { 400 if (cacheType != 0 && cacheType != 1) {
400 // We will be reading directly from file, so can satisfy any 401 // We will be reading directly from file, so can satisfy any
401 // blocksize requirement 402 // blocksize requirement
402 return desired; 403 return desired;
404 return roundedBlockSize; 405 return roundedBlockSize;
405 } 406 }
406 } 407 }
407 408
408 void 409 void
409 WaveFileModel::getSummaries(size_t channel, size_t start, size_t count, 410 WaveFileModel::getSummaries(int channel, int start, int count,
410 RangeBlock &ranges, size_t &blockSize) const 411 RangeBlock &ranges, int &blockSize) const
411 { 412 {
412 ranges.clear(); 413 ranges.clear();
413 if (!isOK()) return; 414 if (!isOK()) return;
414 ranges.reserve((count / blockSize) + 1); 415 ranges.reserve((count / blockSize) + 1);
415 416
420 start = 0; 421 start = 0;
421 } 422 }
422 423
423 int cacheType = 0; 424 int cacheType = 0;
424 int power = m_zoomConstraint.getMinCachePower(); 425 int power = m_zoomConstraint.getMinCachePower();
425 size_t roundedBlockSize = m_zoomConstraint.getNearestBlockSize 426 int roundedBlockSize = m_zoomConstraint.getNearestBlockSize
426 (blockSize, cacheType, power, ZoomConstraint::RoundDown); 427 (blockSize, cacheType, power, ZoomConstraint::RoundDown);
427 428
428 size_t channels = getChannelCount(); 429 int channels = getChannelCount();
429 430
430 if (cacheType != 0 && cacheType != 1) { 431 if (cacheType != 0 && cacheType != 1) {
431 432
432 // We need to read directly from the file. We haven't got 433 // We need to read directly from the file. We haven't got
433 // this cached. Hope the requested area is small. This is 434 // this cached. Hope the requested area is small. This is
447 m_lastDirectReadStart = start; 448 m_lastDirectReadStart = start;
448 m_lastDirectReadCount = count; 449 m_lastDirectReadCount = count;
449 } 450 }
450 451
451 float max = 0.0, min = 0.0, total = 0.0; 452 float max = 0.0, min = 0.0, total = 0.0;
452 size_t i = 0, got = 0; 453 int i = 0, got = 0;
453 454
454 while (i < count) { 455 while (i < count) {
455 456
456 size_t index = i * channels + channel; 457 int index = i * channels + channel;
457 if (index >= m_directRead.size()) break; 458 if (index >= (int)m_directRead.size()) break;
458 459
459 float sample = m_directRead[index]; 460 float sample = m_directRead[index];
460 if (sample > max || got == 0) max = sample; 461 if (sample > max || got == 0) max = sample;
461 if (sample < min || got == 0) min = sample; 462 if (sample < min || got == 0) min = sample;
462 total += fabsf(sample); 463 total += fabsf(sample);
485 486
486 const RangeBlock &cache = m_cache[cacheType]; 487 const RangeBlock &cache = m_cache[cacheType];
487 488
488 blockSize = roundedBlockSize; 489 blockSize = roundedBlockSize;
489 490
490 size_t cacheBlock, div; 491 int cacheBlock, div;
491 492
492 if (cacheType == 0) { 493 if (cacheType == 0) {
493 cacheBlock = (1 << m_zoomConstraint.getMinCachePower()); 494 cacheBlock = (1 << m_zoomConstraint.getMinCachePower());
494 div = (1 << power) / cacheBlock; 495 div = (1 << power) / cacheBlock;
495 } else { 496 } else {
496 cacheBlock = ((unsigned int)((1 << m_zoomConstraint.getMinCachePower()) * sqrt(2.) + 0.01)); 497 cacheBlock = ((unsigned int)((1 << m_zoomConstraint.getMinCachePower()) * sqrt(2.) + 0.01));
497 div = ((unsigned int)((1 << power) * sqrt(2.) + 0.01)) / cacheBlock; 498 div = ((unsigned int)((1 << power) * sqrt(2.) + 0.01)) / cacheBlock;
498 } 499 }
499 500
500 size_t startIndex = start / cacheBlock; 501 int startIndex = start / cacheBlock;
501 size_t endIndex = (start + count) / cacheBlock; 502 int endIndex = (start + count) / cacheBlock;
502 503
503 float max = 0.0, min = 0.0, total = 0.0; 504 float max = 0.0, min = 0.0, total = 0.0;
504 size_t i = 0, got = 0; 505 int i = 0, got = 0;
505 506
506 #ifdef DEBUG_WAVE_FILE_MODEL 507 #ifdef DEBUG_WAVE_FILE_MODEL
507 cerr << "blockSize is " << blockSize << ", cacheBlock " << cacheBlock << ", start " << start << ", count " << count << " (frame count " << getFrameCount() << "), power is " << power << ", div is " << div << ", startIndex " << startIndex << ", endIndex " << endIndex << endl; 508 cerr << "blockSize is " << blockSize << ", cacheBlock " << cacheBlock << ", start " << start << ", count " << count << " (frame count " << getFrameCount() << "), power is " << power << ", div is " << div << ", startIndex " << startIndex << ", endIndex " << endIndex << endl;
508 #endif 509 #endif
509 510
510 for (i = 0; i <= endIndex - startIndex; ) { 511 for (i = 0; i <= endIndex - startIndex; ) {
511 512
512 size_t index = (i + startIndex) * channels + channel; 513 int index = (i + startIndex) * channels + channel;
513 if (index >= cache.size()) break; 514 if (index >= (int)cache.size()) break;
514 515
515 const Range &range = cache[index]; 516 const Range &range = cache[index];
516 if (range.max() > max || got == 0) max = range.max(); 517 if (range.max() > max || got == 0) max = range.max();
517 if (range.min() < min || got == 0) min = range.min(); 518 if (range.min() < min || got == 0) min = range.min();
518 total += range.absmean(); 519 total += range.absmean();
537 #endif 538 #endif
538 return; 539 return;
539 } 540 }
540 541
541 WaveFileModel::Range 542 WaveFileModel::Range
542 WaveFileModel::getSummary(size_t channel, size_t start, size_t count) const 543 WaveFileModel::getSummary(int channel, int start, int count) const
543 { 544 {
544 Range range; 545 Range range;
545 if (!isOK()) return range; 546 if (!isOK()) return range;
546 547
547 if (start > m_startFrame) start -= m_startFrame; 548 if (start > m_startFrame) start -= m_startFrame;
549 else { 550 else {
550 count -= (m_startFrame - start); 551 count -= (m_startFrame - start);
551 start = 0; 552 start = 0;
552 } 553 }
553 554
554 size_t blockSize; 555 int blockSize;
555 for (blockSize = 1; blockSize <= count; blockSize *= 2); 556 for (blockSize = 1; blockSize <= count; blockSize *= 2);
556 if (blockSize > 1) blockSize /= 2; 557 if (blockSize > 1) blockSize /= 2;
557 558
558 bool first = false; 559 bool first = false;
559 560
560 size_t blockStart = (start / blockSize) * blockSize; 561 int blockStart = (start / blockSize) * blockSize;
561 size_t blockEnd = ((start + count) / blockSize) * blockSize; 562 int blockEnd = ((start + count) / blockSize) * blockSize;
562 563
563 if (blockStart < start) blockStart += blockSize; 564 if (blockStart < start) blockStart += blockSize;
564 565
565 if (blockEnd > blockStart) { 566 if (blockEnd > blockStart) {
566 RangeBlock ranges; 567 RangeBlock ranges;
567 getSummaries(channel, blockStart, blockEnd - blockStart, ranges, blockSize); 568 getSummaries(channel, blockStart, blockEnd - blockStart, ranges, blockSize);
568 for (size_t i = 0; i < ranges.size(); ++i) { 569 for (int i = 0; i < (int)ranges.size(); ++i) {
569 if (first || ranges[i].min() < range.min()) range.setMin(ranges[i].min()); 570 if (first || ranges[i].min() < range.min()) range.setMin(ranges[i].min());
570 if (first || ranges[i].max() > range.max()) range.setMax(ranges[i].max()); 571 if (first || ranges[i].max() > range.max()) range.setMax(ranges[i].max());
571 if (first || ranges[i].absmean() < range.absmean()) range.setAbsmean(ranges[i].absmean()); 572 if (first || ranges[i].absmean() < range.absmean()) range.setAbsmean(ranges[i].absmean());
572 first = false; 573 first = false;
573 } 574 }
612 613
613 void 614 void
614 WaveFileModel::fillTimerTimedOut() 615 WaveFileModel::fillTimerTimedOut()
615 { 616 {
616 if (m_fillThread) { 617 if (m_fillThread) {
617 size_t fillExtent = m_fillThread->getFillExtent(); 618 int fillExtent = m_fillThread->getFillExtent();
618 #ifdef DEBUG_WAVE_FILE_MODEL 619 #ifdef DEBUG_WAVE_FILE_MODEL
619 SVDEBUG << "WaveFileModel::fillTimerTimedOut: extent = " << fillExtent << endl; 620 SVDEBUG << "WaveFileModel::fillTimerTimedOut: extent = " << fillExtent << endl;
620 #endif 621 #endif
621 if (fillExtent > m_lastFillExtent) { 622 if (fillExtent > m_lastFillExtent) {
622 emit modelChanged(m_lastFillExtent, fillExtent); 623 emit modelChangedWithin(m_lastFillExtent, fillExtent);
623 m_lastFillExtent = fillExtent; 624 m_lastFillExtent = fillExtent;
624 } 625 }
625 } else { 626 } else {
626 #ifdef DEBUG_WAVE_FILE_MODEL 627 #ifdef DEBUG_WAVE_FILE_MODEL
627 SVDEBUG << "WaveFileModel::fillTimerTimedOut: no thread" << endl; 628 SVDEBUG << "WaveFileModel::fillTimerTimedOut: no thread" << endl;
638 m_fillThread = 0; 639 m_fillThread = 0;
639 delete m_updateTimer; 640 delete m_updateTimer;
640 m_updateTimer = 0; 641 m_updateTimer = 0;
641 m_mutex.unlock(); 642 m_mutex.unlock();
642 if (getEndFrame() > m_lastFillExtent) { 643 if (getEndFrame() > m_lastFillExtent) {
643 emit modelChanged(m_lastFillExtent, getEndFrame()); 644 emit modelChangedWithin(m_lastFillExtent, getEndFrame());
644 } 645 }
645 emit modelChanged(); 646 emit modelChanged();
646 emit ready(); 647 emit ready();
647 #ifdef DEBUG_WAVE_FILE_MODEL 648 #ifdef DEBUG_WAVE_FILE_MODEL
648 SVDEBUG << "WaveFileModel::cacheFilled" << endl; 649 SVDEBUG << "WaveFileModel::cacheFilled" << endl;
650 } 651 }
651 652
652 void 653 void
653 WaveFileModel::RangeCacheFillThread::run() 654 WaveFileModel::RangeCacheFillThread::run()
654 { 655 {
655 size_t cacheBlockSize[2]; 656 int cacheBlockSize[2];
656 cacheBlockSize[0] = (1 << m_model.m_zoomConstraint.getMinCachePower()); 657 cacheBlockSize[0] = (1 << m_model.m_zoomConstraint.getMinCachePower());
657 cacheBlockSize[1] = ((unsigned int)((1 << m_model.m_zoomConstraint.getMinCachePower()) * 658 cacheBlockSize[1] = ((unsigned int)((1 << m_model.m_zoomConstraint.getMinCachePower()) *
658 sqrt(2.) + 0.01)); 659 sqrt(2.) + 0.01));
659 660
660 size_t frame = 0; 661 int frame = 0;
661 int readBlockSize = 16384; 662 int readBlockSize = 16384;
662 SampleBlock block; 663 SampleBlock block;
663 664
664 if (!m_model.isOK()) return; 665 if (!m_model.isOK()) return;
665 666
666 size_t channels = m_model.getChannelCount(); 667 int channels = m_model.getChannelCount();
667 bool updating = m_model.m_reader->isUpdating(); 668 bool updating = m_model.m_reader->isUpdating();
668 669
669 if (updating) { 670 if (updating) {
670 while (channels == 0 && !m_model.m_exiting) { 671 while (channels == 0 && !m_model.m_exiting) {
671 // SVDEBUG << "WaveFileModel::fill: Waiting for channels..." << endl; 672 // SVDEBUG << "WaveFileModel::fill: Waiting for channels..." << endl;
674 } 675 }
675 } 676 }
676 677
677 Range *range = new Range[2 * channels]; 678 Range *range = new Range[2 * channels];
678 float *means = new float[2 * channels]; 679 float *means = new float[2 * channels];
679 size_t count[2]; 680 int count[2];
680 count[0] = count[1] = 0; 681 count[0] = count[1] = 0;
681 for (int i = 0; i < 2 * channels; ++i) { 682 for (int i = 0; i < 2 * channels; ++i) {
682 means[i] = 0.f; 683 means[i] = 0.f;
683 } 684 }
684 685
701 702
702 // cerr << "block is " << block.size() << endl; 703 // cerr << "block is " << block.size() << endl;
703 704
704 for (int i = 0; i < readBlockSize; ++i) { 705 for (int i = 0; i < readBlockSize; ++i) {
705 706
706 if (channels * i + channels > block.size()) break; 707 if (channels * i + channels > (int)block.size()) break;
707 708
708 for (int ch = 0; ch < channels; ++ch) { 709 for (int ch = 0; ch < channels; ++ch) {
709 710
710 int index = channels * i + ch; 711 int index = channels * i + ch;
711 float sample = block[index]; 712 float sample = block[index];
725 } 726 }
726 } 727 }
727 728
728 QMutexLocker locker(&m_model.m_mutex); 729 QMutexLocker locker(&m_model.m_mutex);
729 730
730 for (size_t ct = 0; ct < 2; ++ct) { 731 for (int ct = 0; ct < 2; ++ct) {
731 732
732 if (++count[ct] == cacheBlockSize[ct]) { 733 if (++count[ct] == cacheBlockSize[ct]) {
733 734
734 for (size_t ch = 0; ch < size_t(channels); ++ch) { 735 for (int ch = 0; ch < int(channels); ++ch) {
735 size_t rangeIndex = ch * 2 + ct; 736 int rangeIndex = ch * 2 + ct;
736 means[rangeIndex] /= count[ct]; 737 means[rangeIndex] /= count[ct];
737 range[rangeIndex].setAbsmean(means[rangeIndex]); 738 range[rangeIndex].setAbsmean(means[rangeIndex]);
738 m_model.m_cache[ct].push_back(range[rangeIndex]); 739 m_model.m_cache[ct].push_back(range[rangeIndex]);
739 range[rangeIndex] = Range(); 740 range[rangeIndex] = Range();
740 means[rangeIndex] = 0.f; 741 means[rangeIndex] = 0.f;
764 765
765 if (!m_model.m_exiting) { 766 if (!m_model.m_exiting) {
766 767
767 QMutexLocker locker(&m_model.m_mutex); 768 QMutexLocker locker(&m_model.m_mutex);
768 769
769 for (size_t ct = 0; ct < 2; ++ct) { 770 for (int ct = 0; ct < 2; ++ct) {
770 771
771 if (count[ct] > 0) { 772 if (count[ct] > 0) {
772 773
773 for (size_t ch = 0; ch < size_t(channels); ++ch) { 774 for (int ch = 0; ch < int(channels); ++ch) {
774 size_t rangeIndex = ch * 2 + ct; 775 int rangeIndex = ch * 2 + ct;
775 means[rangeIndex] /= count[ct]; 776 means[rangeIndex] /= count[ct];
776 range[rangeIndex].setAbsmean(means[rangeIndex]); 777 range[rangeIndex].setAbsmean(means[rangeIndex]);
777 m_model.m_cache[ct].push_back(range[rangeIndex]); 778 m_model.m_cache[ct].push_back(range[rangeIndex]);
778 range[rangeIndex] = Range(); 779 range[rangeIndex] = Range();
779 means[rangeIndex] = 0.f; 780 means[rangeIndex] = 0.f;
791 delete[] range; 792 delete[] range;
792 793
793 m_fillExtent = m_frameCount; 794 m_fillExtent = m_frameCount;
794 795
795 #ifdef DEBUG_WAVE_FILE_MODEL 796 #ifdef DEBUG_WAVE_FILE_MODEL
796 for (size_t ct = 0; ct < 2; ++ct) { 797 for (int ct = 0; ct < 2; ++ct) {
797 cerr << "Cache type " << ct << " now contains " << m_model.m_cache[ct].size() << " ranges" << endl; 798 cerr << "Cache type " << ct << " now contains " << m_model.m_cache[ct].size() << " ranges" << endl;
798 } 799 }
799 #endif 800 #endif
800 } 801 }
801 802