changeset 1507:fe579dc6a713 import-audio-data

Merge from default branch
author Chris Cannam
date Tue, 04 Sep 2018 13:19:20 +0100
parents f0c2b8b31609 (diff) a250a54c11cc (current diff)
children b837ccdd4946
files
diffstat 8 files changed, 149 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/base/ProgressReporter.h	Tue Sep 04 11:31:35 2018 +0100
+++ b/base/ProgressReporter.h	Tue Sep 04 13:19:20 2018 +0100
@@ -13,8 +13,8 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef _PROGRESS_REPORTER_H_
-#define _PROGRESS_REPORTER_H_
+#ifndef SV_PROGRESS_REPORTER_H
+#define SV_PROGRESS_REPORTER_H
 
 #include <QObject>
 #include <QString>
--- a/data/fileio/CSVFileReader.cpp	Tue Sep 04 11:31:35 2018 +0100
+++ b/data/fileio/CSVFileReader.cpp	Tue Sep 04 13:19:20 2018 +0100
@@ -18,11 +18,13 @@
 #include "model/Model.h"
 #include "base/RealTime.h"
 #include "base/StringBits.h"
+#include "base/ProgressReporter.h"
 #include "model/SparseOneDimensionalModel.h"
 #include "model/SparseTimeValueModel.h"
 #include "model/EditableDenseThreeDimensionalModel.h"
 #include "model/RegionModel.h"
 #include "model/NoteModel.h"
+#include "model/WritableWaveFileModel.h"
 #include "DataFileReaderFactory.h"
 
 #include <QFile>
@@ -39,12 +41,17 @@
 using namespace std;
 
 CSVFileReader::CSVFileReader(QString path, CSVFormat format,
-                             sv_samplerate_t mainModelSampleRate) :
+                             sv_samplerate_t mainModelSampleRate,
+                             ProgressReporter *reporter) :
     m_format(format),
     m_device(0),
     m_ownDevice(true),
     m_warnings(0),
-    m_mainModelSampleRate(mainModelSampleRate)
+    m_mainModelSampleRate(mainModelSampleRate),
+    m_fileSize(0),
+    m_readCount(0),
+    m_progress(-1),
+    m_reporter(reporter)
 {
     QFile *file = new QFile(path);
     bool good = false;
@@ -60,19 +67,27 @@
     if (good) {
         m_device = file;
         m_filename = QFileInfo(path).fileName();
+        m_fileSize = file->size();
+        if (m_reporter) m_reporter->setDefinite(true);
     } else {
         delete file;
     }
 }
 
 CSVFileReader::CSVFileReader(QIODevice *device, CSVFormat format,
-                             sv_samplerate_t mainModelSampleRate) :
+                             sv_samplerate_t mainModelSampleRate,
+                             ProgressReporter *reporter) :
     m_format(format),
     m_device(device),
     m_ownDevice(false),
     m_warnings(0),
-    m_mainModelSampleRate(mainModelSampleRate)
+    m_mainModelSampleRate(mainModelSampleRate),
+    m_fileSize(0),
+    m_readCount(0),
+    m_progress(-1),
+    m_reporter(reporter)
 {
+    if (m_reporter) m_reporter->setDefinite(false);
 }
 
 CSVFileReader::~CSVFileReader()
@@ -184,6 +199,7 @@
     RegionModel *model2a = 0;
     NoteModel *model2b = 0;
     EditableDenseThreeDimensionalModel *model3 = 0;
+    WritableWaveFileModel *modelW = 0;
     Model *model = 0;
 
     QTextStream in(m_device);
@@ -228,6 +244,25 @@
 
         QString chunk = in.readLine();
         QStringList lines = chunk.split('\r', QString::SkipEmptyParts);
+
+        m_readCount += chunk.size() + 1;
+
+        if (m_reporter) {
+            if (m_reporter->wasCancelled()) {
+                break;
+            }
+            int progress;
+            if (m_fileSize > 0) {
+                progress = int((double(m_readCount) / double(m_fileSize))
+                               * 100.0);
+            } else {
+                progress = int(m_readCount / 10000);
+            }
+            if (progress != m_progress) {
+                m_reporter->setProgress(progress);
+                m_progress = progress;
+            }
+        }
         
         for (int li = 0; li < lines.size(); ++li) {
 
@@ -268,6 +303,12 @@
                          EditableDenseThreeDimensionalModel::NoCompression);
                     model = model3;
                     break;
+
+                case CSVFormat::WaveFileModel:
+                    modelW = new WritableWaveFileModel
+                        (sampleRate, valueColumns);
+                    model = modelW;
+                    break;
                 }
 
                 if (model) {
@@ -402,8 +443,47 @@
 //                          << frameNo << ", time " << RealTime::frame2RealTime(frameNo, sampleRate) << endl;
 
                 model3->setColumn(lineno, values);
+
+            } else if (modelType == CSVFormat::WaveFileModel) {
+
+                int channels = modelW->getChannelCount();
+                
+                float **samples =
+                    breakfastquay::allocate_and_zero_channels<float>
+                    (channels, 1);
+
+                int channel = 0;
+                
+                for (int i = 0; i < list.size() && channel < channels; ++i) {
+
+                    if (m_format.getColumnPurpose(i) !=
+                        CSVFormat::ColumnValue) {
+                        continue;
+                    }
+
+                    bool ok = false;
+                    float value = list[i].toFloat(&ok);
+                    
+                    samples[channel][0] = value;
+
+                    ++channel;
+                }
+
+                bool ok = modelW->addSamples(samples, 1);
+
+                breakfastquay::deallocate_channels(samples, channels);
+                
+                if (!ok) {
+                    if (warnings < warnLimit) {
+                        SVCERR << "WARNING: CSVFileReader::load: "
+                               << "Unable to add sample to wave-file model"
+                               << endl;
+                        SVCERR << line << endl;
+                        ++warnings;
+                    }
+                }
             }
-
+            
             ++lineno;
             if (timingType == CSVFormat::ImplicitTiming ||
                 list.size() == 0) {
@@ -479,6 +559,11 @@
         model3->setMaximumLevel(max);
     }
 
+    if (modelW) {
+        modelW->updateModel();
+        modelW->writeComplete();
+    }
+
     return model;
 }
 
--- a/data/fileio/CSVFileReader.h	Tue Sep 04 11:31:35 2018 +0100
+++ b/data/fileio/CSVFileReader.h	Tue Sep 04 13:19:20 2018 +0100
@@ -27,6 +27,7 @@
 #include <QIODevice>
 
 class QFile;
+class ProgressReporter;
 
 class CSVFileReader : public DataFileReader
 {
@@ -35,7 +36,9 @@
      * Construct a CSVFileReader to read the CSV file at the given
      * path, with the given format.
      */
-    CSVFileReader(QString path, CSVFormat format, sv_samplerate_t mainModelSampleRate);
+    CSVFileReader(QString path, CSVFormat format,
+                  sv_samplerate_t mainModelSampleRate,
+                  ProgressReporter *reporter = 0);
 
     /**
      * Construct a CSVFileReader to read from the given
@@ -43,7 +46,9 @@
      * CSVFileReader will not close or delete it and it must outlive
      * the CSVFileReader.
      */
-    CSVFileReader(QIODevice *device, CSVFormat format, sv_samplerate_t mainModelSampleRate);
+    CSVFileReader(QIODevice *device, CSVFormat format,
+                  sv_samplerate_t mainModelSampleRate,
+                  ProgressReporter *reporter = 0);
 
     virtual ~CSVFileReader();
 
@@ -60,6 +65,10 @@
     QString m_error;
     mutable int m_warnings;
     sv_samplerate_t m_mainModelSampleRate;
+    qint64 m_fileSize;
+    mutable qint64 m_readCount;
+    mutable int m_progress;
+    ProgressReporter *m_reporter;
 
     sv_frame_t convertTimeValue(QString, int lineno, sv_samplerate_t sampleRate,
                                 int windowSize) const;
--- a/data/fileio/CSVFormat.h	Tue Sep 04 11:31:35 2018 +0100
+++ b/data/fileio/CSVFormat.h	Tue Sep 04 13:19:20 2018 +0100
@@ -29,7 +29,8 @@
         TwoDimensionalModel,
         TwoDimensionalModelWithDuration,
         TwoDimensionalModelWithDurationAndPitch,
-        ThreeDimensionalModel
+        ThreeDimensionalModel,
+        WaveFileModel
     };
     
     enum TimingType {
--- a/data/fileio/DataFileReaderFactory.cpp	Tue Sep 04 11:31:35 2018 +0100
+++ b/data/fileio/DataFileReaderFactory.cpp	Tue Sep 04 13:19:20 2018 +0100
@@ -32,21 +32,28 @@
                                     bool csv,
                                     MIDIFileImportPreferenceAcquirer *acquirer,
                                     CSVFormat format,
-                                    sv_samplerate_t mainModelSampleRate)
+                                    sv_samplerate_t mainModelSampleRate,
+                                    ProgressReporter *reporter)
 {
     QString err;
 
     DataFileReader *reader = 0;
 
     if (!csv) {
-        reader = new MIDIFileReader(path, acquirer, mainModelSampleRate);
+        reader = new MIDIFileReader(path,
+                                    acquirer,
+                                    mainModelSampleRate,
+                                    reporter);
         if (reader->isOK()) return reader;
         if (reader->getError() != "") err = reader->getError();
         delete reader;
     }
 
     if (csv) {
-        reader = new CSVFileReader(path, format, mainModelSampleRate);
+        reader = new CSVFileReader(path,
+                                   format,
+                                   mainModelSampleRate,
+                                   reporter);
         if (reader->isOK()) return reader;
         if (reader->getError() != "") err = reader->getError();
         delete reader;
@@ -58,14 +65,15 @@
 DataFileReader *
 DataFileReaderFactory::createReader(QString path,
                                     MIDIFileImportPreferenceAcquirer *acquirer,
-                                    sv_samplerate_t mainModelSampleRate)
+                                    sv_samplerate_t mainModelSampleRate,
+                                    ProgressReporter *reporter)
 {
     DataFileReader *reader = createReader
-        (path, false, acquirer, CSVFormat(), mainModelSampleRate);
+        (path, false, acquirer, CSVFormat(), mainModelSampleRate, reporter);
     if (reader) return reader;
 
     reader = createReader
-        (path, true, acquirer, CSVFormat(path), mainModelSampleRate);
+        (path, true, acquirer, CSVFormat(path), mainModelSampleRate, reporter);
     if (reader) return reader;
 
     return 0;
@@ -74,11 +82,13 @@
 Model *
 DataFileReaderFactory::load(QString path,
                             MIDIFileImportPreferenceAcquirer *acquirer,
-                            sv_samplerate_t mainModelSampleRate)
+                            sv_samplerate_t mainModelSampleRate,
+                            ProgressReporter *reporter)
 {
     DataFileReader *reader = createReader(path,
                                           acquirer,
-                                          mainModelSampleRate);
+                                          mainModelSampleRate,
+                                          reporter);
     if (!reader) return NULL;
 
     try {
@@ -94,12 +104,14 @@
 Model *
 DataFileReaderFactory::loadNonCSV(QString path,
                                   MIDIFileImportPreferenceAcquirer *acquirer,
-                                  sv_samplerate_t mainModelSampleRate)
+                                  sv_samplerate_t mainModelSampleRate,
+                                  ProgressReporter *reporter)
 {
     DataFileReader *reader = createReader(path, false,
                                           acquirer,
                                           CSVFormat(),
-                                          mainModelSampleRate);
+                                          mainModelSampleRate,
+                                          reporter);
     if (!reader) return NULL;
 
     try {
@@ -114,10 +126,12 @@
 
 Model *
 DataFileReaderFactory::loadCSV(QString path, CSVFormat format,
-                               sv_samplerate_t mainModelSampleRate)
+                               sv_samplerate_t mainModelSampleRate,
+                               ProgressReporter *reporter)
 {
     DataFileReader *reader = createReader(path, true, 0, format,
-                                          mainModelSampleRate);
+                                          mainModelSampleRate,
+                                          reporter);
     if (!reader) return NULL;
 
     try {
--- a/data/fileio/DataFileReaderFactory.h	Tue Sep 04 11:31:35 2018 +0100
+++ b/data/fileio/DataFileReaderFactory.h	Tue Sep 04 13:19:20 2018 +0100
@@ -13,8 +13,8 @@
     COPYING included with this distribution for more information.
 */
 
-#ifndef _DATA_FILE_READER_FACTORY_H_
-#define _DATA_FILE_READER_FACTORY_H_
+#ifndef SV_DATA_FILE_READER_FACTORY_H
+#define SV_DATA_FILE_READER_FACTORY_H
 
 #include <QString>
 
@@ -23,6 +23,7 @@
 
 class DataFileReader;
 class Model;
+class ProgressReporter;
 
 class DataFileReaderFactory
 {
@@ -48,7 +49,8 @@
      */
     static DataFileReader *createReader(QString path,
                                         MIDIFileImportPreferenceAcquirer *,
-                                        sv_samplerate_t mainModelSampleRate);
+                                        sv_samplerate_t mainModelSampleRate,
+                                        ProgressReporter *reporter = 0);
 
     /**
      * Read the given path, if a suitable reader is available.
@@ -60,7 +62,8 @@
      */
     static Model *load(QString path,
                        MIDIFileImportPreferenceAcquirer *acquirer,
-                       sv_samplerate_t mainModelSampleRate);
+                       sv_samplerate_t mainModelSampleRate,
+                       ProgressReporter *reporter = 0);
 
     /**
      * Read the given path, if a suitable reader is available.
@@ -69,7 +72,8 @@
      */
     static Model *loadNonCSV(QString path,
                              MIDIFileImportPreferenceAcquirer *acquirer,
-                             sv_samplerate_t mainModelSampleRate);
+                             sv_samplerate_t mainModelSampleRate,
+                             ProgressReporter *reporter = 0);
 
     /**
      * Read the given path using the CSV reader with the given format.
@@ -77,13 +81,15 @@
      */
     static Model *loadCSV(QString path,
                           CSVFormat format,
-                          sv_samplerate_t mainModelSampleRate);
+                          sv_samplerate_t mainModelSampleRate,
+                          ProgressReporter *reporter = 0);
 
 protected:
     static DataFileReader *createReader(QString path, bool csv,
                                         MIDIFileImportPreferenceAcquirer *,
                                         CSVFormat format,
-                                        sv_samplerate_t mainModelSampleRate);
+                                        sv_samplerate_t mainModelSampleRate,
+                                        ProgressReporter *reporter = 0);
 };
 
 #endif
--- a/data/fileio/MIDIFileReader.cpp	Tue Sep 04 11:31:35 2018 +0100
+++ b/data/fileio/MIDIFileReader.cpp	Tue Sep 04 13:19:20 2018 +0100
@@ -58,7 +58,8 @@
 
 MIDIFileReader::MIDIFileReader(QString path,
                                MIDIFileImportPreferenceAcquirer *acquirer,
-                               sv_samplerate_t mainModelSampleRate) :
+                               sv_samplerate_t mainModelSampleRate,
+                               ProgressReporter *) : // we don't actually report progress
     m_smpte(false),
     m_timingDivision(0),
     m_fps(0),
--- a/data/fileio/MIDIFileReader.h	Tue Sep 04 11:31:35 2018 +0100
+++ b/data/fileio/MIDIFileReader.h	Tue Sep 04 13:19:20 2018 +0100
@@ -31,6 +31,7 @@
 #include <QObject>
 
 class MIDIEvent;
+class ProgressReporter;
 
 typedef unsigned char MIDIByte;
 
@@ -61,7 +62,8 @@
 public:
     MIDIFileReader(QString path,
                    MIDIFileImportPreferenceAcquirer *pref, // may be null
-                   sv_samplerate_t mainModelSampleRate);
+                   sv_samplerate_t mainModelSampleRate,
+                   ProgressReporter *reporter = 0);
     virtual ~MIDIFileReader();
 
     virtual bool isOK() const;