void
WavFileReader::getInterleavedFrames(size_t start, size_t count,
				    SampleBlock &results) const
{
    if (count == 0) return;
    results.clear();
    results.reserve(count * m_fileInfo.channels);

    QMutexLocker locker(&m_mutex);

    if (!m_file || !m_channelCount) {
        return;
    }

    if ((long)start >= m_fileInfo.frames) {
//        SVDEBUG << "WavFileReader::getInterleavedFrames: " << start
//                  << " > " << m_fileInfo.frames << endl;
	return;
    }

    if (long(start + count) > m_fileInfo.frames) {
	count = m_fileInfo.frames - start;
    }

    sf_count_t readCount = 0;

    if (start != m_lastStart || count != m_lastCount) {

	if (sf_seek(m_file, start, SEEK_SET) < 0) {
//            std::cerr << "sf_seek failed" << std::endl;
	    return;
	}
	
	if (count * m_fileInfo.channels > m_bufsiz) {
//	    std::cerr << "WavFileReader: Reallocating buffer for " << count
//		      << " frames, " << m_fileInfo.channels << " channels: "
//		      << m_bufsiz << " floats" << std::endl;
	    m_bufsiz = count * m_fileInfo.channels;
	    delete[] m_buffer;
	    m_buffer = new float[m_bufsiz];
	}
	
	if ((readCount = sf_readf_float(m_file, m_buffer, count)) < 0) {
//            std::cerr << "sf_readf_float failed" << std::endl;
	    return;
	}

	m_lastStart = start;
	m_lastCount = readCount;
    }

    for (size_t i = 0; i < count * m_fileInfo.channels; ++i) {
        if (i >= m_bufsiz) {
            std::cerr << "INTERNAL ERROR: WavFileReader::getInterleavedFrames: " << i << " >= " << m_bufsiz << std::endl;
        }
	results.push_back(m_buffer[i]);
    }

    return;
}
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]);
        }
    }
}
示例#3
0
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
}