changeset 107:7b60603966cf multiplex

Implementation of MultiplexedReader -- now builds, not yet tested
author Chris Cannam
date Thu, 02 Oct 2014 08:16:42 +0100
parents de76b2df518f
children ca565b18ba3e
files runner.pro runner/FeatureExtractionManager.cpp runner/MultiplexedReader.cpp runner/MultiplexedReader.h
diffstat 4 files changed, 114 insertions(+), 59 deletions(-) [+]
line wrap: on
line diff
--- a/runner.pro	Wed Oct 01 18:38:32 2014 +0100
+++ b/runner.pro	Thu Oct 02 08:16:42 2014 +0100
@@ -67,14 +67,16 @@
 	runner/AudioDBFeatureWriter.h \
         runner/FeatureWriterFactory.h  \
         runner/DefaultFeatureWriter.h \
-        runner/FeatureExtractionManager.h
+        runner/FeatureExtractionManager.h \
+        runner/MultiplexedReader.h
 
 SOURCES += \
 	runner/main.cpp \
 	runner/DefaultFeatureWriter.cpp \
 	runner/FeatureExtractionManager.cpp \
         runner/AudioDBFeatureWriter.cpp \
-        runner/FeatureWriterFactory.cpp
+        runner/FeatureWriterFactory.cpp \
+        runner/MultiplexedReader.cpp
 
 !win32 {
     QMAKE_POST_LINK=/bin/bash tests/test.sh
--- a/runner/FeatureExtractionManager.cpp	Wed Oct 01 18:38:32 2014 +0100
+++ b/runner/FeatureExtractionManager.cpp	Thu Oct 02 08:16:42 2014 +0100
@@ -587,6 +587,7 @@
 AudioFileReader *
 FeatureExtractionManager::prepareReader(QString source)
 {
+    AudioFileReader *reader = 0;
     if (m_readyReaders.contains(source)) {
         reader = m_readyReaders[source];
         m_readyReaders.remove(source);
@@ -605,7 +606,7 @@
         retrievalProgress.done();
     }
     if (!reader) {
-        throw FailedToOpenFile(audioSource);
+        throw FailedToOpenFile(source);
     }
     return reader;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/runner/MultiplexedReader.cpp	Thu Oct 02 08:16:42 2014 +0100
@@ -0,0 +1,96 @@
+/* -*- 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 count,
+					SampleBlock &frames) const
+{
+    int nr = m_readers.size();
+
+    frames = SampleBlock(count * nr);
+
+    for (int ri = 0; ri < nr; ++ri) {
+
+	AudioFileReader *reader = m_readers[ri];
+	SampleBlock rs(count * reader->getChannelCount());
+
+	reader->getInterleavedFrames(start, count, rs);
+
+	int nc = reader->getChannelCount();
+	for (int i = 0; i < count; ++i) {
+	    for (int c = 0; c < nc; ++c) {
+		frames[i * nr + ri] += rs[i * nc + c];
+	    }
+	}
+    }
+}
+
+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;
+}
+
+
+    
--- a/runner/MultiplexedReader.h	Wed Oct 01 18:38:32 2014 +0100
+++ b/runner/MultiplexedReader.h	Thu Oct 02 08:16:42 2014 +0100
@@ -21,73 +21,29 @@
 #include <QString>
 #include <QList>
 
-typedef std::vector<float> SampleBlock;
-
-class MultiplexedReader : public QObject
+class MultiplexedReader : public AudioFileReader
 {
     Q_OBJECT
 
 public:
+    // I take ownership of readers
     MultiplexedReader(QList<AudioFileReader *> readers);
-    virtual ~MultiplexedReader() { }
+    virtual ~MultiplexedReader();
 
-    //!!! the rest of this is currently still from AudioFileReader.h! Finish!
+    virtual QString getError() const { return m_error; }
+    virtual bool isQuicklySeekable() const { return m_quicklySeekable; }
 
+    virtual void getInterleavedFrames(int start, int count,
+				      SampleBlock &frames) const;
 
+    virtual int getDecodeCompletion() const;
 
+    virtual bool isUpdating() const;
 
-    bool isOK() const { return (m_channelCount > 0); }
-
-    virtual QString getError() const { return ""; }
-
-    int getFrameCount() const { return m_frameCount; }
-    int getChannelCount() const { return m_channelCount; }
-    int getSampleRate() const { return m_sampleRate; }
-
-    virtual int getNativeRate() const { return m_sampleRate; } // if resampled
-
-    /**
-     * Return true if this file supports fast seek and random
-     * access. Typically this will be true for uncompressed formats
-     * and false for compressed ones.
-     */
-    virtual bool isQuicklySeekable() const = 0;
-
-    /** 
-     * Return interleaved samples for count frames from index start.
-     * The resulting sample block will contain count *
-     * getChannelCount() samples (or fewer if end of file is reached).
-     *
-     * The subclass implementations of this function must be
-     * thread-safe -- that is, safe to call from multiple threads with
-     * different arguments on the same object at the same time.
-     */
-    virtual void getInterleavedFrames(int start, int count,
-				      SampleBlock &frames) const = 0;
-
-    /**
-     * Return de-interleaved samples for count frames from index
-     * start.  Implemented in this class (it calls
-     * getInterleavedFrames and de-interleaves).  The resulting vector
-     * will contain getChannelCount() sample blocks of count samples
-     * each (or fewer if end of file is reached).
-     */
-    virtual void getDeInterleavedFrames(int start, int count,
-                                        std::vector<SampleBlock> &frames) const;
-
-    // only subclasses that do not know exactly how long the audio
-    // file is until it's been completely decoded should implement this
-    virtual int getDecodeCompletion() const { return 100; } // %
-
-    virtual bool isUpdating() const { return false; }
-
-signals:
-    void frameCountChanged();
-    
 protected:
-    int m_frameCount;
-    int m_channelCount;
-    int m_sampleRate;
+    QString m_error;
+    bool m_quicklySeekable;
+    QList<AudioFileReader *> m_readers;
 };
 
 #endif