void AudioFileReader::getDeInterleavedFrames(size_t start, size_t count, std::vector<SampleBlock> &frames) const { SampleBlock interleaved; getInterleavedFrames(start, count, interleaved); size_t channels = getChannelCount(); size_t rc = interleaved.size() / channels; frames.clear(); for (size_t c = 0; c < channels; ++c) { frames.push_back(SampleBlock()); } for (size_t i = 0; i < rc; ++i) { for (size_t c = 0; c < channels; ++c) { frames[c].push_back(interleaved[i * channels + c]); } } }
void WaveFileModel::RangeCacheFillThread::run() { size_t cacheBlockSize[2]; cacheBlockSize[0] = (1 << m_model.m_zoomConstraint.getMinCachePower()); cacheBlockSize[1] = ((unsigned int)((1 << m_model.m_zoomConstraint.getMinCachePower()) * sqrt(2.) + 0.01)); size_t frame = 0; int readBlockSize = 16384; SampleBlock block; if (!m_model.isOK()) return; size_t channels = m_model.getChannelCount(); bool updating = m_model.m_reader->isUpdating(); if (updating) { while (channels == 0 && !m_model.m_exiting) { // std::cerr << "WaveFileModel::fill: Waiting for channels..." << std::endl; sleep(1); channels = m_model.getChannelCount(); } } Range *range = new Range[2 * channels]; float *means = new float[2 * channels]; size_t count[2]; count[0] = count[1] = 0; for (int i = 0; i < 2 * channels; ++i) { means[i] = 0.f; } bool first = true; while (first || updating) { updating = m_model.m_reader->isUpdating(); m_frameCount = m_model.getFrameCount(); // std::cerr << "WaveFileModel::fill: frame = " << frame << ", count = " << m_frameCount << std::endl; while (frame < m_frameCount) { // std::cerr << "WaveFileModel::fill inner loop: frame = " << frame << ", count = " << m_frameCount << ", blocksize " << readBlockSize << std::endl; if (updating && (frame + readBlockSize > m_frameCount)) break; m_model.m_reader->getInterleavedFrames(frame, readBlockSize, block); // std::cerr << "block is " << block.size() << std::endl; for (int i = 0; i < readBlockSize; ++i) { if (channels * i + channels > block.size()) break; for (int ch = 0; ch < channels; ++ch) { int index = channels * i + ch; float sample = block[index]; for (int ct = 0; ct < 2; ++ct) { // cache type int rangeIndex = ch * 2 + ct; if (sample > range[rangeIndex].max() || count[ct] == 0) { range[rangeIndex].setMax(sample); } if (sample < range[rangeIndex].min() || count[ct] == 0) { range[rangeIndex].setMin(sample); } means[rangeIndex] += fabsf(sample); } } QMutexLocker locker(&m_model.m_mutex); for (size_t ct = 0; ct < 2; ++ct) { if (++count[ct] == cacheBlockSize[ct]) { for (size_t ch = 0; ch < size_t(channels); ++ch) { size_t rangeIndex = ch * 2 + ct; means[rangeIndex] /= count[ct]; range[rangeIndex].setAbsmean(means[rangeIndex]); m_model.m_cache[ct].push_back(range[rangeIndex]); range[rangeIndex] = Range(); means[rangeIndex] = 0.f; } count[ct] = 0; } } ++frame; } if (m_model.m_exiting) break; m_fillExtent = frame; } // std::cerr << "WaveFileModel: inner loop ended" << std::endl; first = false; if (m_model.m_exiting) break; if (updating) { // std::cerr << "sleeping..." << std::endl; sleep(1); } } if (!m_model.m_exiting) { QMutexLocker locker(&m_model.m_mutex); for (size_t ct = 0; ct < 2; ++ct) { if (count[ct] > 0) { for (size_t ch = 0; ch < size_t(channels); ++ch) { size_t rangeIndex = ch * 2 + ct; means[rangeIndex] /= count[ct]; range[rangeIndex].setAbsmean(means[rangeIndex]); m_model.m_cache[ct].push_back(range[rangeIndex]); range[rangeIndex] = Range(); means[rangeIndex] = 0.f; } count[ct] = 0; } const Range &rr = *m_model.m_cache[ct].begin(); MUNLOCK(&rr, m_model.m_cache[ct].capacity() * sizeof(Range)); } } delete[] means; delete[] range; m_fillExtent = m_frameCount; #ifdef DEBUG_WAVE_FILE_MODEL for (size_t ct = 0; ct < 2; ++ct) { cerr << "Cache type " << ct << " now contains " << m_model.m_cache[ct].size() << " ranges" << endl; } #endif }