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