view runner/MultiplexedReader.cpp @ 179:766268a32378 sonic-annotator-1.1

Further doc and note updates
author Chris Cannam
date Thu, 16 Oct 2014 13:05:53 +0100
parents 34a0dad473c3
children 3287df4588dd
line wrap: on
line source
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */

/*
    Sonic Annotator
    A utility for batch feature extraction from audio files.
    Mark Levy, Chris Sutton and Chris Cannam, Queen Mary, University of London.
    Copyright 2007-2014 QMUL.

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of the
    License, or (at your option) any later version.  See the file
    COPYING included with this distribution for more information.
*/

#include "MultiplexedReader.h"

MultiplexedReader::MultiplexedReader(QList<AudioFileReader *> readers) : 
    m_readers(readers)
{
    m_channelCount = readers.size();
    m_sampleRate = readers[0]->getSampleRate();
    
    m_frameCount = 0;
    m_quicklySeekable = true;
    
    foreach (AudioFileReader *r, m_readers) {
	if (!r->isOK()) {
	    m_channelCount = 0;
	    m_error = r->getError();
	} else {
	    if (r->getFrameCount() > m_frameCount) {
		m_frameCount = r->getFrameCount();
	    }
	    if (!r->isQuicklySeekable()) {
		m_quicklySeekable = false;
	    }
	}
    }
}

MultiplexedReader::~MultiplexedReader()
{
    foreach (AudioFileReader *r, m_readers) {
	delete r;
    }
}

void
MultiplexedReader::getInterleavedFrames(int start, int frameCount,
					SampleBlock &block) const
{
    int out_chans = m_readers.size();

    // Allocate and zero
    block = SampleBlock(frameCount * out_chans, 0.f);

    for (int out_chan = 0; out_chan < out_chans; ++out_chan) {

	AudioFileReader *reader = m_readers[out_chan];
	SampleBlock readerBlock;
	reader->getInterleavedFrames(start, frameCount, readerBlock);

	int in_chans = reader->getChannelCount();

	for (int frame = 0; frame < frameCount; ++frame) {

            int out_index = frame * out_chans + out_chan;

	    for (int in_chan = 0; in_chan < in_chans; ++in_chan) {
                int in_index = frame * in_chans + in_chan;
                if (in_index >= (int)readerBlock.size()) break;
		block[out_index] += readerBlock[in_index];
	    }

            if (in_chans > 1) {
                block[out_index] /= float(in_chans);
            }
	}
    }
}

int
MultiplexedReader::getDecodeCompletion() const
{
    int completion = 100;
    foreach (AudioFileReader *r, m_readers) {
	int c = r->getDecodeCompletion();
	if (c < 100) {
	    completion = c;
	}
    }
    return completion;
}

bool
MultiplexedReader::isUpdating() const
{
    foreach (AudioFileReader *r, m_readers) {
	if (r->isUpdating()) return true;
    }
    return false;
}