Mercurial > hg > svcore
comparison data/model/WaveFileModel.cpp @ 1057:5c5d4863b428 tonioni
Merge from cxx11 branch
author | Chris Cannam |
---|---|
date | Mon, 23 Mar 2015 11:26:28 +0000 |
parents | 48e4ffa9fb48 |
children | 0fd3661bcfff |
comparison
equal
deleted
inserted
replaced
1056:c4898e57eea5 | 1057:5c5d4863b428 |
---|---|
35 //#define DEBUG_WAVE_FILE_MODEL 1 | 35 //#define DEBUG_WAVE_FILE_MODEL 1 |
36 | 36 |
37 PowerOfSqrtTwoZoomConstraint | 37 PowerOfSqrtTwoZoomConstraint |
38 WaveFileModel::m_zoomConstraint; | 38 WaveFileModel::m_zoomConstraint; |
39 | 39 |
40 WaveFileModel::WaveFileModel(FileSource source, int targetRate) : | 40 WaveFileModel::WaveFileModel(FileSource source, sv_samplerate_t targetRate) : |
41 m_source(source), | 41 m_source(source), |
42 m_path(source.getLocation()), | 42 m_path(source.getLocation()), |
43 m_reader(0), | 43 m_reader(0), |
44 m_myReader(true), | 44 m_myReader(true), |
45 m_startFrame(0), | 45 m_startFrame(0), |
129 { | 129 { |
130 WaveFileModel *model = new WaveFileModel(m_source); | 130 WaveFileModel *model = new WaveFileModel(m_source); |
131 return model; | 131 return model; |
132 } | 132 } |
133 | 133 |
134 int | 134 sv_frame_t |
135 WaveFileModel::getFrameCount() const | 135 WaveFileModel::getFrameCount() const |
136 { | 136 { |
137 if (!m_reader) return 0; | 137 if (!m_reader) return 0; |
138 return m_reader->getFrameCount(); | 138 return m_reader->getFrameCount(); |
139 } | 139 } |
143 { | 143 { |
144 if (!m_reader) return 0; | 144 if (!m_reader) return 0; |
145 return m_reader->getChannelCount(); | 145 return m_reader->getChannelCount(); |
146 } | 146 } |
147 | 147 |
148 int | 148 sv_samplerate_t |
149 WaveFileModel::getSampleRate() const | 149 WaveFileModel::getSampleRate() const |
150 { | 150 { |
151 if (!m_reader) return 0; | 151 if (!m_reader) return 0; |
152 return m_reader->getSampleRate(); | 152 return m_reader->getSampleRate(); |
153 } | 153 } |
154 | 154 |
155 int | 155 sv_samplerate_t |
156 WaveFileModel::getNativeRate() const | 156 WaveFileModel::getNativeRate() const |
157 { | 157 { |
158 if (!m_reader) return 0; | 158 if (!m_reader) return 0; |
159 int rate = m_reader->getNativeRate(); | 159 sv_samplerate_t rate = m_reader->getNativeRate(); |
160 if (rate == 0) rate = getSampleRate(); | 160 if (rate == 0) rate = getSampleRate(); |
161 return rate; | 161 return rate; |
162 } | 162 } |
163 | 163 |
164 QString | 164 QString |
189 { | 189 { |
190 if (m_reader) return m_reader->getLocalFilename(); | 190 if (m_reader) return m_reader->getLocalFilename(); |
191 return ""; | 191 return ""; |
192 } | 192 } |
193 | 193 |
194 int | 194 sv_frame_t |
195 WaveFileModel::getData(int channel, int start, int count, | 195 WaveFileModel::getData(int channel, sv_frame_t start, sv_frame_t count, |
196 float *buffer) const | 196 float *buffer) const |
197 { | 197 { |
198 // Always read these directly from the file. | 198 // Always read these directly from the file. |
199 // This is used for e.g. audio playback. | 199 // This is used for e.g. audio playback. |
200 // Could be much more efficient (although compiler optimisation will help) | 200 // Could be much more efficient (although compiler optimisation will help) |
204 #endif | 204 #endif |
205 | 205 |
206 if (start >= m_startFrame) { | 206 if (start >= m_startFrame) { |
207 start -= m_startFrame; | 207 start -= m_startFrame; |
208 } else { | 208 } else { |
209 for (int i = 0; i < count; ++i) { | 209 for (sv_frame_t i = 0; i < count; ++i) { |
210 buffer[i] = 0.f; | 210 buffer[i] = 0.f; |
211 } | 211 } |
212 if (count <= m_startFrame - start) { | 212 if (count <= m_startFrame - start) { |
213 return 0; | 213 return 0; |
214 } else { | 214 } else { |
216 start = 0; | 216 start = 0; |
217 } | 217 } |
218 } | 218 } |
219 | 219 |
220 if (!m_reader || !m_reader->isOK() || count == 0) { | 220 if (!m_reader || !m_reader->isOK() || count == 0) { |
221 for (int i = 0; i < count; ++i) buffer[i] = 0.f; | 221 for (sv_frame_t i = 0; i < count; ++i) buffer[i] = 0.f; |
222 return 0; | 222 return 0; |
223 } | 223 } |
224 | 224 |
225 #ifdef DEBUG_WAVE_FILE_MODEL | 225 #ifdef DEBUG_WAVE_FILE_MODEL |
226 // SVDEBUG << "WaveFileModel::getValues(" << channel << ", " | 226 // SVDEBUG << "WaveFileModel::getValues(" << channel << ", " |
227 // << start << ", " << end << "): calling reader" << endl; | 227 // << start << ", " << end << "): calling reader" << endl; |
228 #endif | 228 #endif |
229 | 229 |
230 int channels = getChannelCount(); | 230 int channels = getChannelCount(); |
231 | 231 |
232 SampleBlock frames(count * channels); | 232 SampleBlock frames = m_reader->getInterleavedFrames(start, count); |
233 m_reader->getInterleavedFrames(start, count, frames); | 233 |
234 | 234 sv_frame_t i = 0; |
235 int i = 0; | |
236 | 235 |
237 int ch0 = channel, ch1 = channel; | 236 int ch0 = channel, ch1 = channel; |
238 if (channel == -1) { | 237 if (channel == -1) { |
239 ch0 = 0; | 238 ch0 = 0; |
240 ch1 = channels - 1; | 239 ch1 = channels - 1; |
244 | 243 |
245 buffer[i] = 0.0; | 244 buffer[i] = 0.0; |
246 | 245 |
247 for (int ch = ch0; ch <= ch1; ++ch) { | 246 for (int ch = ch0; ch <= ch1; ++ch) { |
248 | 247 |
249 int index = i * channels + ch; | 248 sv_frame_t index = i * channels + ch; |
250 if (index >= (int)frames.size()) break; | 249 if (index >= (sv_frame_t)frames.size()) break; |
251 | 250 |
252 float sample = frames[index]; | 251 float sample = frames[index]; |
253 buffer[i] += sample; | 252 buffer[i] += sample; |
254 } | 253 } |
255 | 254 |
257 } | 256 } |
258 | 257 |
259 return i; | 258 return i; |
260 } | 259 } |
261 | 260 |
262 int | 261 sv_frame_t |
263 WaveFileModel::getData(int channel, int start, int count, | 262 WaveFileModel::getData(int channel, sv_frame_t start, sv_frame_t count, |
264 double *buffer) const | 263 double *buffer) const |
265 { | 264 { |
266 #ifdef DEBUG_WAVE_FILE_MODEL | 265 #ifdef DEBUG_WAVE_FILE_MODEL |
267 cout << "WaveFileModel::getData(double)[" << this << "]: " << channel << ", " << start << ", " << count << ", " << buffer << endl; | 266 cout << "WaveFileModel::getData(double)[" << this << "]: " << channel << ", " << start << ", " << count << ", " << buffer << endl; |
268 #endif | 267 #endif |
269 | 268 |
270 if (start > m_startFrame) { | 269 if (start > m_startFrame) { |
271 start -= m_startFrame; | 270 start -= m_startFrame; |
272 } else { | 271 } else { |
273 for (int i = 0; i < count; ++i) buffer[i] = 0.0; | 272 for (sv_frame_t i = 0; i < count; ++i) buffer[i] = 0.0; |
274 if (count <= m_startFrame - start) { | 273 if (count <= m_startFrame - start) { |
275 return 0; | 274 return 0; |
276 } else { | 275 } else { |
277 count -= (m_startFrame - start); | 276 count -= (m_startFrame - start); |
278 start = 0; | 277 start = 0; |
279 } | 278 } |
280 } | 279 } |
281 | 280 |
282 if (!m_reader || !m_reader->isOK() || count == 0) { | 281 if (!m_reader || !m_reader->isOK() || count == 0) { |
283 for (int i = 0; i < count; ++i) buffer[i] = 0.0; | 282 for (sv_frame_t i = 0; i < count; ++i) buffer[i] = 0.0; |
284 return 0; | 283 return 0; |
285 } | 284 } |
286 | 285 |
287 int channels = getChannelCount(); | 286 int channels = getChannelCount(); |
288 | 287 |
289 SampleBlock frames(count * channels); | 288 SampleBlock frames = m_reader->getInterleavedFrames(start, count); |
290 m_reader->getInterleavedFrames(start, count, frames); | 289 |
291 | 290 sv_frame_t i = 0; |
292 int i = 0; | |
293 | 291 |
294 int ch0 = channel, ch1 = channel; | 292 int ch0 = channel, ch1 = channel; |
295 if (channel == -1) { | 293 if (channel == -1) { |
296 ch0 = 0; | 294 ch0 = 0; |
297 ch1 = channels - 1; | 295 ch1 = channels - 1; |
301 | 299 |
302 buffer[i] = 0.0; | 300 buffer[i] = 0.0; |
303 | 301 |
304 for (int ch = ch0; ch <= ch1; ++ch) { | 302 for (int ch = ch0; ch <= ch1; ++ch) { |
305 | 303 |
306 int index = i * channels + ch; | 304 sv_frame_t index = i * channels + ch; |
307 if (index >= (int)frames.size()) break; | 305 if (index >= (sv_frame_t)frames.size()) break; |
308 | 306 |
309 float sample = frames[index]; | 307 float sample = frames[index]; |
310 buffer[i] += sample; | 308 buffer[i] += sample; |
311 } | 309 } |
312 | 310 |
314 } | 312 } |
315 | 313 |
316 return i; | 314 return i; |
317 } | 315 } |
318 | 316 |
319 int | 317 sv_frame_t |
320 WaveFileModel::getData(int fromchannel, int tochannel, | 318 WaveFileModel::getData(int fromchannel, int tochannel, |
321 int start, int count, | 319 sv_frame_t start, sv_frame_t count, |
322 float **buffer) const | 320 float **buffer) const |
323 { | 321 { |
324 #ifdef DEBUG_WAVE_FILE_MODEL | 322 #ifdef DEBUG_WAVE_FILE_MODEL |
325 cout << "WaveFileModel::getData[" << this << "]: " << fromchannel << "," << tochannel << ", " << start << ", " << count << ", " << buffer << endl; | 323 cout << "WaveFileModel::getData[" << this << "]: " << fromchannel << "," << tochannel << ", " << start << ", " << count << ", " << buffer << endl; |
326 #endif | 324 #endif |
353 | 351 |
354 if (start >= m_startFrame) { | 352 if (start >= m_startFrame) { |
355 start -= m_startFrame; | 353 start -= m_startFrame; |
356 } else { | 354 } else { |
357 for (int c = 0; c < reqchannels; ++c) { | 355 for (int c = 0; c < reqchannels; ++c) { |
358 for (int i = 0; i < count; ++i) buffer[c][i] = 0.f; | 356 for (sv_frame_t i = 0; i < count; ++i) buffer[c][i] = 0.f; |
359 } | 357 } |
360 if (count <= m_startFrame - start) { | 358 if (count <= m_startFrame - start) { |
361 return 0; | 359 return 0; |
362 } else { | 360 } else { |
363 count -= (m_startFrame - start); | 361 count -= (m_startFrame - start); |
365 } | 363 } |
366 } | 364 } |
367 | 365 |
368 if (!m_reader || !m_reader->isOK() || count == 0) { | 366 if (!m_reader || !m_reader->isOK() || count == 0) { |
369 for (int c = 0; c < reqchannels; ++c) { | 367 for (int c = 0; c < reqchannels; ++c) { |
370 for (int i = 0; i < count; ++i) buffer[c][i] = 0.f; | 368 for (sv_frame_t i = 0; i < count; ++i) buffer[c][i] = 0.f; |
371 } | 369 } |
372 return 0; | 370 return 0; |
373 } | 371 } |
374 | 372 |
375 SampleBlock frames(count * channels); | 373 SampleBlock frames = m_reader->getInterleavedFrames(start, count); |
376 m_reader->getInterleavedFrames(start, count, frames); | 374 |
377 | 375 sv_frame_t i = 0; |
378 int i = 0; | 376 |
379 | 377 sv_frame_t index = 0, available = frames.size(); |
380 int index = 0, available = frames.size(); | |
381 | 378 |
382 while (i < count) { | 379 while (i < count) { |
383 | 380 |
384 if (index >= available) break; | 381 if (index >= available) break; |
385 | 382 |
416 return roundedBlockSize; | 413 return roundedBlockSize; |
417 } | 414 } |
418 } | 415 } |
419 | 416 |
420 void | 417 void |
421 WaveFileModel::getSummaries(int channel, int start, int count, | 418 WaveFileModel::getSummaries(int channel, sv_frame_t start, sv_frame_t count, |
422 RangeBlock &ranges, int &blockSize) const | 419 RangeBlock &ranges, int &blockSize) const |
423 { | 420 { |
424 ranges.clear(); | 421 ranges.clear(); |
425 if (!isOK()) return; | 422 if (!isOK()) return; |
426 ranges.reserve((count / blockSize) + 1); | 423 ranges.reserve((count / blockSize) + 1); |
453 | 450 |
454 if (m_lastDirectReadStart != start || | 451 if (m_lastDirectReadStart != start || |
455 m_lastDirectReadCount != count || | 452 m_lastDirectReadCount != count || |
456 m_directRead.empty()) { | 453 m_directRead.empty()) { |
457 | 454 |
458 m_reader->getInterleavedFrames(start, count, m_directRead); | 455 m_directRead = m_reader->getInterleavedFrames(start, count); |
459 m_lastDirectReadStart = start; | 456 m_lastDirectReadStart = start; |
460 m_lastDirectReadCount = count; | 457 m_lastDirectReadCount = count; |
461 } | 458 } |
462 | 459 |
463 float max = 0.0, min = 0.0, total = 0.0; | 460 float max = 0.0, min = 0.0, total = 0.0; |
464 int i = 0, got = 0; | 461 sv_frame_t i = 0, got = 0; |
465 | 462 |
466 while (i < count) { | 463 while (i < count) { |
467 | 464 |
468 int index = i * channels + channel; | 465 sv_frame_t index = i * channels + channel; |
469 if (index >= (int)m_directRead.size()) break; | 466 if (index >= (sv_frame_t)m_directRead.size()) break; |
470 | 467 |
471 float sample = m_directRead[index]; | 468 float sample = m_directRead[index]; |
472 if (sample > max || got == 0) max = sample; | 469 if (sample > max || got == 0) max = sample; |
473 if (sample < min || got == 0) min = sample; | 470 if (sample < min || got == 0) min = sample; |
474 total += fabsf(sample); | 471 total += fabsf(sample); |
475 | 472 |
476 ++i; | 473 ++i; |
477 ++got; | 474 ++got; |
478 | 475 |
479 if (got == blockSize) { | 476 if (got == blockSize) { |
480 ranges.push_back(Range(min, max, total / got)); | 477 ranges.push_back(Range(min, max, total / float(got))); |
481 min = max = total = 0.0f; | 478 min = max = total = 0.0f; |
482 got = 0; | 479 got = 0; |
483 } | 480 } |
484 } | 481 } |
485 | 482 |
486 m_directReadMutex.unlock(); | 483 m_directReadMutex.unlock(); |
487 | 484 |
488 if (got > 0) { | 485 if (got > 0) { |
489 ranges.push_back(Range(min, max, total / got)); | 486 ranges.push_back(Range(min, max, total / float(got))); |
490 } | 487 } |
491 | 488 |
492 return; | 489 return; |
493 | 490 |
494 } else { | 491 } else { |
497 | 494 |
498 const RangeBlock &cache = m_cache[cacheType]; | 495 const RangeBlock &cache = m_cache[cacheType]; |
499 | 496 |
500 blockSize = roundedBlockSize; | 497 blockSize = roundedBlockSize; |
501 | 498 |
502 int cacheBlock, div; | 499 sv_frame_t cacheBlock, div; |
503 | 500 |
504 if (cacheType == 0) { | 501 if (cacheType == 0) { |
505 cacheBlock = (1 << m_zoomConstraint.getMinCachePower()); | 502 cacheBlock = (1 << m_zoomConstraint.getMinCachePower()); |
506 div = (1 << power) / cacheBlock; | 503 div = (1 << power) / cacheBlock; |
507 } else { | 504 } else { |
508 cacheBlock = ((unsigned int)((1 << m_zoomConstraint.getMinCachePower()) * sqrt(2.) + 0.01)); | 505 cacheBlock = sv_frame_t((1 << m_zoomConstraint.getMinCachePower()) * sqrt(2.) + 0.01); |
509 div = ((unsigned int)((1 << power) * sqrt(2.) + 0.01)) / cacheBlock; | 506 div = sv_frame_t(((1 << power) * sqrt(2.) + 0.01) / double(cacheBlock)); |
510 } | 507 } |
511 | 508 |
512 int startIndex = start / cacheBlock; | 509 sv_frame_t startIndex = start / cacheBlock; |
513 int endIndex = (start + count) / cacheBlock; | 510 sv_frame_t endIndex = (start + count) / cacheBlock; |
514 | 511 |
515 float max = 0.0, min = 0.0, total = 0.0; | 512 float max = 0.0, min = 0.0, total = 0.0; |
516 int i = 0, got = 0; | 513 sv_frame_t i = 0, got = 0; |
517 | 514 |
518 #ifdef DEBUG_WAVE_FILE_MODEL | 515 #ifdef DEBUG_WAVE_FILE_MODEL |
519 cerr << "blockSize is " << blockSize << ", cacheBlock " << cacheBlock << ", start " << start << ", count " << count << " (frame count " << getFrameCount() << "), power is " << power << ", div is " << div << ", startIndex " << startIndex << ", endIndex " << endIndex << endl; | 516 cerr << "blockSize is " << blockSize << ", cacheBlock " << cacheBlock << ", start " << start << ", count " << count << " (frame count " << getFrameCount() << "), power is " << power << ", div is " << div << ", startIndex " << startIndex << ", endIndex " << endIndex << endl; |
520 #endif | 517 #endif |
521 | 518 |
522 for (i = 0; i <= endIndex - startIndex; ) { | 519 for (i = 0; i <= endIndex - startIndex; ) { |
523 | 520 |
524 int index = (i + startIndex) * channels + channel; | 521 sv_frame_t index = (i + startIndex) * channels + channel; |
525 if (index >= (int)cache.size()) break; | 522 if (index >= (sv_frame_t)cache.size()) break; |
526 | 523 |
527 const Range &range = cache[index]; | 524 const Range &range = cache[index]; |
528 if (range.max() > max || got == 0) max = range.max(); | 525 if (range.max() > max || got == 0) max = range.max(); |
529 if (range.min() < min || got == 0) min = range.min(); | 526 if (range.min() < min || got == 0) min = range.min(); |
530 total += range.absmean(); | 527 total += range.absmean(); |
531 | 528 |
532 ++i; | 529 ++i; |
533 ++got; | 530 ++got; |
534 | 531 |
535 if (got == div) { | 532 if (got == div) { |
536 ranges.push_back(Range(min, max, total / got)); | 533 ranges.push_back(Range(min, max, total / float(got))); |
537 min = max = total = 0.0f; | 534 min = max = total = 0.0f; |
538 got = 0; | 535 got = 0; |
539 } | 536 } |
540 } | 537 } |
541 | 538 |
542 if (got > 0) { | 539 if (got > 0) { |
543 ranges.push_back(Range(min, max, total / got)); | 540 ranges.push_back(Range(min, max, total / float(got))); |
544 } | 541 } |
545 } | 542 } |
546 | 543 |
547 #ifdef DEBUG_WAVE_FILE_MODEL | 544 #ifdef DEBUG_WAVE_FILE_MODEL |
548 SVDEBUG << "returning " << ranges.size() << " ranges" << endl; | 545 SVDEBUG << "returning " << ranges.size() << " ranges" << endl; |
549 #endif | 546 #endif |
550 return; | 547 return; |
551 } | 548 } |
552 | 549 |
553 WaveFileModel::Range | 550 WaveFileModel::Range |
554 WaveFileModel::getSummary(int channel, int start, int count) const | 551 WaveFileModel::getSummary(int channel, sv_frame_t start, sv_frame_t count) const |
555 { | 552 { |
556 Range range; | 553 Range range; |
557 if (!isOK()) return range; | 554 if (!isOK()) return range; |
558 | 555 |
559 if (start > m_startFrame) start -= m_startFrame; | 556 if (start > m_startFrame) start -= m_startFrame; |
567 for (blockSize = 1; blockSize <= count; blockSize *= 2); | 564 for (blockSize = 1; blockSize <= count; blockSize *= 2); |
568 if (blockSize > 1) blockSize /= 2; | 565 if (blockSize > 1) blockSize /= 2; |
569 | 566 |
570 bool first = false; | 567 bool first = false; |
571 | 568 |
572 int blockStart = (start / blockSize) * blockSize; | 569 sv_frame_t blockStart = (start / blockSize) * blockSize; |
573 int blockEnd = ((start + count) / blockSize) * blockSize; | 570 sv_frame_t blockEnd = ((start + count) / blockSize) * blockSize; |
574 | 571 |
575 if (blockStart < start) blockStart += blockSize; | 572 if (blockStart < start) blockStart += blockSize; |
576 | 573 |
577 if (blockEnd > blockStart) { | 574 if (blockEnd > blockStart) { |
578 RangeBlock ranges; | 575 RangeBlock ranges; |
624 | 621 |
625 void | 622 void |
626 WaveFileModel::fillTimerTimedOut() | 623 WaveFileModel::fillTimerTimedOut() |
627 { | 624 { |
628 if (m_fillThread) { | 625 if (m_fillThread) { |
629 int fillExtent = m_fillThread->getFillExtent(); | 626 sv_frame_t fillExtent = m_fillThread->getFillExtent(); |
630 #ifdef DEBUG_WAVE_FILE_MODEL | 627 #ifdef DEBUG_WAVE_FILE_MODEL |
631 SVDEBUG << "WaveFileModel::fillTimerTimedOut: extent = " << fillExtent << endl; | 628 SVDEBUG << "WaveFileModel::fillTimerTimedOut: extent = " << fillExtent << endl; |
632 #endif | 629 #endif |
633 if (fillExtent > m_lastFillExtent) { | 630 if (fillExtent > m_lastFillExtent) { |
634 emit modelChangedWithin(m_lastFillExtent, fillExtent); | 631 emit modelChangedWithin(m_lastFillExtent, fillExtent); |
664 void | 661 void |
665 WaveFileModel::RangeCacheFillThread::run() | 662 WaveFileModel::RangeCacheFillThread::run() |
666 { | 663 { |
667 int cacheBlockSize[2]; | 664 int cacheBlockSize[2]; |
668 cacheBlockSize[0] = (1 << m_model.m_zoomConstraint.getMinCachePower()); | 665 cacheBlockSize[0] = (1 << m_model.m_zoomConstraint.getMinCachePower()); |
669 cacheBlockSize[1] = ((unsigned int)((1 << m_model.m_zoomConstraint.getMinCachePower()) * | 666 cacheBlockSize[1] = (int((1 << m_model.m_zoomConstraint.getMinCachePower()) * |
670 sqrt(2.) + 0.01)); | 667 sqrt(2.) + 0.01)); |
671 | 668 |
672 int frame = 0; | 669 sv_frame_t frame = 0; |
673 int readBlockSize = 16384; | 670 const sv_frame_t readBlockSize = 16384; |
674 SampleBlock block; | 671 SampleBlock block; |
675 | 672 |
676 if (!m_model.isOK()) return; | 673 if (!m_model.isOK()) return; |
677 | 674 |
678 int channels = m_model.getChannelCount(); | 675 int channels = m_model.getChannelCount(); |
707 | 704 |
708 // SVDEBUG << "WaveFileModel::fill inner loop: frame = " << frame << ", count = " << m_frameCount << ", blocksize " << readBlockSize << endl; | 705 // SVDEBUG << "WaveFileModel::fill inner loop: frame = " << frame << ", count = " << m_frameCount << ", blocksize " << readBlockSize << endl; |
709 | 706 |
710 if (updating && (frame + readBlockSize > m_frameCount)) break; | 707 if (updating && (frame + readBlockSize > m_frameCount)) break; |
711 | 708 |
712 m_model.m_reader->getInterleavedFrames(frame, readBlockSize, block); | 709 block = m_model.m_reader->getInterleavedFrames(frame, readBlockSize); |
713 | 710 |
714 // cerr << "block is " << block.size() << endl; | 711 // cerr << "block is " << block.size() << endl; |
715 | 712 |
716 for (int i = 0; i < readBlockSize; ++i) { | 713 for (sv_frame_t i = 0; i < readBlockSize; ++i) { |
717 | 714 |
718 if (channels * i + channels > (int)block.size()) break; | 715 if (channels * i + channels > (int)block.size()) break; |
719 | 716 |
720 for (int ch = 0; ch < channels; ++ch) { | 717 for (int ch = 0; ch < channels; ++ch) { |
721 | 718 |
722 int index = channels * i + ch; | 719 sv_frame_t index = channels * i + ch; |
723 float sample = block[index]; | 720 float sample = block[index]; |
724 | 721 |
725 for (int ct = 0; ct < 2; ++ct) { // cache type | 722 for (int cacheType = 0; cacheType < 2; ++cacheType) { // cache type |
726 | 723 |
727 int rangeIndex = ch * 2 + ct; | 724 sv_frame_t rangeIndex = ch * 2 + cacheType; |
728 | 725 range[rangeIndex].sample(sample); |
729 if (sample > range[rangeIndex].max() || count[ct] == 0) { | |
730 range[rangeIndex].setMax(sample); | |
731 } | |
732 if (sample < range[rangeIndex].min() || count[ct] == 0) { | |
733 range[rangeIndex].setMin(sample); | |
734 } | |
735 | |
736 means[rangeIndex] += fabsf(sample); | 726 means[rangeIndex] += fabsf(sample); |
737 } | 727 } |
738 } | 728 } |
739 | 729 |
730 //!!! this looks like a ludicrous way to do synchronisation | |
740 QMutexLocker locker(&m_model.m_mutex); | 731 QMutexLocker locker(&m_model.m_mutex); |
741 | 732 |
742 for (int ct = 0; ct < 2; ++ct) { | 733 for (int cacheType = 0; cacheType < 2; ++cacheType) { |
743 | 734 |
744 if (++count[ct] == cacheBlockSize[ct]) { | 735 if (++count[cacheType] == cacheBlockSize[cacheType]) { |
745 | 736 |
746 for (int ch = 0; ch < int(channels); ++ch) { | 737 for (int ch = 0; ch < int(channels); ++ch) { |
747 int rangeIndex = ch * 2 + ct; | 738 int rangeIndex = ch * 2 + cacheType; |
748 means[rangeIndex] /= count[ct]; | 739 means[rangeIndex] = means[rangeIndex] / float(count[cacheType]); |
749 range[rangeIndex].setAbsmean(means[rangeIndex]); | 740 range[rangeIndex].setAbsmean(means[rangeIndex]); |
750 m_model.m_cache[ct].push_back(range[rangeIndex]); | 741 m_model.m_cache[cacheType].push_back(range[rangeIndex]); |
751 range[rangeIndex] = Range(); | 742 range[rangeIndex] = Range(); |
752 means[rangeIndex] = 0.f; | 743 means[rangeIndex] = 0.f; |
753 } | 744 } |
754 | 745 |
755 count[ct] = 0; | 746 count[cacheType] = 0; |
756 } | 747 } |
757 } | 748 } |
758 | 749 |
759 ++frame; | 750 ++frame; |
760 } | 751 } |
776 | 767 |
777 if (!m_model.m_exiting) { | 768 if (!m_model.m_exiting) { |
778 | 769 |
779 QMutexLocker locker(&m_model.m_mutex); | 770 QMutexLocker locker(&m_model.m_mutex); |
780 | 771 |
781 for (int ct = 0; ct < 2; ++ct) { | 772 for (int cacheType = 0; cacheType < 2; ++cacheType) { |
782 | 773 |
783 if (count[ct] > 0) { | 774 if (count[cacheType] > 0) { |
784 | 775 |
785 for (int ch = 0; ch < int(channels); ++ch) { | 776 for (int ch = 0; ch < int(channels); ++ch) { |
786 int rangeIndex = ch * 2 + ct; | 777 int rangeIndex = ch * 2 + cacheType; |
787 means[rangeIndex] /= count[ct]; | 778 means[rangeIndex] = means[rangeIndex] / float(count[cacheType]); |
788 range[rangeIndex].setAbsmean(means[rangeIndex]); | 779 range[rangeIndex].setAbsmean(means[rangeIndex]); |
789 m_model.m_cache[ct].push_back(range[rangeIndex]); | 780 m_model.m_cache[cacheType].push_back(range[rangeIndex]); |
790 range[rangeIndex] = Range(); | 781 range[rangeIndex] = Range(); |
791 means[rangeIndex] = 0.f; | 782 means[rangeIndex] = 0.f; |
792 } | 783 } |
793 | 784 |
794 count[ct] = 0; | 785 count[cacheType] = 0; |
795 } | 786 } |
796 | 787 |
797 const Range &rr = *m_model.m_cache[ct].begin(); | 788 const Range &rr = *m_model.m_cache[cacheType].begin(); |
798 MUNLOCK(&rr, m_model.m_cache[ct].capacity() * sizeof(Range)); | 789 MUNLOCK(&rr, m_model.m_cache[cacheType].capacity() * sizeof(Range)); |
799 } | 790 } |
800 } | 791 } |
801 | 792 |
802 delete[] means; | 793 delete[] means; |
803 delete[] range; | 794 delete[] range; |
804 | 795 |
805 m_fillExtent = m_frameCount; | 796 m_fillExtent = m_frameCount; |
806 | 797 |
807 #ifdef DEBUG_WAVE_FILE_MODEL | 798 #ifdef DEBUG_WAVE_FILE_MODEL |
808 for (int ct = 0; ct < 2; ++ct) { | 799 for (int cacheType = 0; cacheType < 2; ++cacheType) { |
809 cerr << "Cache type " << ct << " now contains " << m_model.m_cache[ct].size() << " ranges" << endl; | 800 cerr << "Cache type " << cacheType << " now contains " << m_model.m_cache[cacheType].size() << " ranges" << endl; |
810 } | 801 } |
811 #endif | 802 #endif |
812 } | 803 } |
813 | 804 |
814 void | 805 void |