diff data/model/WritableWaveFileModel.cpp @ 175:b0f4555b625e

* Introduce WritableWaveFileModel, and use it as an output model for audio real-time plugin transforms. Updates aren't working correctly yet.
author Chris Cannam
date Tue, 03 Oct 2006 14:17:37 +0000
parents
children 570794f6f6a7
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/data/model/WritableWaveFileModel.cpp	Tue Oct 03 14:17:37 2006 +0000
@@ -0,0 +1,191 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2006 Chris Cannam.
+    
+    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 "WritableWaveFileModel.h"
+
+#include "base/TempDirectory.h"
+#include "base/Exceptions.h"
+
+#include "fileio/WavFileWriter.h"
+#include "fileio/WavFileReader.h"
+
+#include <QDir>
+
+#include <cassert>
+#include <iostream>
+
+WritableWaveFileModel::WritableWaveFileModel(size_t sampleRate,
+					     size_t channels,
+					     QString path) :
+    m_model(0),
+    m_writer(0),
+    m_reader(0),
+    m_sampleRate(sampleRate),
+    m_channels(channels),
+    m_frameCount(0)
+{
+    if (path.isEmpty()) {
+        try {
+            QDir dir(TempDirectory::getInstance()->getPath());
+            path = dir.filePath(QString("written_%1.wav")
+                                .arg((intptr_t)this));
+        } catch (DirectoryCreationFailed f) {
+            std::cerr << "WritableWaveFileModel: Failed to create temporary directory" << std::endl;
+            return;
+        }
+    }
+
+    m_writer = new WavFileWriter(path, sampleRate, channels);
+    if (!m_writer->isOK()) {
+        std::cerr << "WritableWaveFileModel: Error in creating WAV file writer: " << m_writer->getError().toStdString() << std::endl;
+        delete m_writer; 
+        m_writer = 0;
+        return;
+    }
+}
+
+WritableWaveFileModel::~WritableWaveFileModel()
+{
+    delete m_model;
+    delete m_writer;
+    delete m_reader;
+}
+
+bool
+WritableWaveFileModel::addSamples(float **samples, size_t count)
+{
+    if (!m_writer) return false;
+
+    if (!m_writer->writeSamples(samples, count)) {
+        std::cerr << "ERROR: WritableWaveFileModel::addSamples: writer failed: " << m_writer->getError().toStdString() << std::endl;
+        return false;
+    }
+
+    m_frameCount += count;
+
+    if (!m_model) {
+
+        m_reader = new WavFileReader(m_writer->getPath());
+        if (!m_reader->getError().isEmpty()) {
+            std::cerr << "WritableWaveFileModel: Error in creating wave file reader" << std::endl;
+            delete m_reader;
+            m_reader = 0;
+            return false;
+        }
+
+        m_model = new WaveFileModel(m_writer->getPath(), m_reader);
+        if (!m_model->isOK()) {
+            std::cerr << "WritableWaveFileModel: Error in creating wave file model" << std::endl;
+            delete m_model;
+            m_model = 0;
+            delete m_reader;
+            m_reader = 0;
+            return false;
+        }
+    }
+    
+    static int updateCounter = 0;
+    if (++updateCounter == 100) {
+        if (m_reader) m_reader->updateFrameCount();
+        updateCounter = 0;
+    }
+
+    return true;
+}
+
+void
+WritableWaveFileModel::sync()
+{
+    if (m_reader) m_reader->updateFrameCount();
+}    
+
+bool
+WritableWaveFileModel::isOK() const
+{
+    bool ok = (m_model && m_model->isOK());
+    std::cerr << "WritableWaveFileModel::isOK(): ok = " << ok << std::endl;
+    return ok;
+}
+
+bool
+WritableWaveFileModel::isReady(int *completion) const
+{
+    bool ready = (m_model && m_model->isReady(completion));
+    std::cerr << "WritableWaveFileModel::isReady(): ready = " << ready << std::endl;
+    return ready;
+}
+
+size_t
+WritableWaveFileModel::getFrameCount() const
+{
+    std::cerr << "WritableWaveFileModel::getFrameCount: count = " << m_frameCount << std::endl;
+    return m_frameCount;
+}
+
+Model *
+WritableWaveFileModel::clone() const
+{
+    assert(0); //!!!
+}
+
+size_t
+WritableWaveFileModel::getValues(int channel, size_t start, size_t end,
+                                 float *buffer) const
+{
+    if (!m_model) return 0;
+    return m_model->getValues(channel, start, end, buffer);
+}
+
+size_t
+WritableWaveFileModel::getValues(int channel, size_t start, size_t end,
+                                 double *buffer) const
+{
+    if (!m_model) return 0;
+//    std::cerr << "WritableWaveFileModel::getValues(" << channel << ", "
+//              << start << ", " << end << "): calling model" << std::endl;
+    return m_model->getValues(channel, start, end, buffer);
+}
+
+WritableWaveFileModel::RangeBlock
+WritableWaveFileModel::getRanges(size_t channel, size_t start, size_t end,
+                                 size_t &blockSize) const
+{
+    if (!m_model) return RangeBlock();
+    return m_model->getRanges(channel, start, end, blockSize);
+}
+
+WritableWaveFileModel::Range
+WritableWaveFileModel::getRange(size_t channel, size_t start, size_t end) const
+{
+    if (!m_model) return Range();
+    return m_model->getRange(channel, start, end);
+}
+
+void
+WritableWaveFileModel::toXml(QTextStream &out,
+                             QString indent,
+                             QString extraAttributes) const
+{
+    assert(0); //!!!
+}
+
+QString
+WritableWaveFileModel::toXmlString(QString indent,
+                                   QString extraAttributes) const
+{
+    assert(0); //!!!
+    return "";
+}
+