Chris@175: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@175: Chris@175: /* Chris@175: Sonic Visualiser Chris@175: An audio file viewer and annotation editor. Chris@175: Centre for Digital Music, Queen Mary, University of London. Chris@175: This file copyright 2006 Chris Cannam. Chris@175: Chris@175: This program is free software; you can redistribute it and/or Chris@175: modify it under the terms of the GNU General Public License as Chris@175: published by the Free Software Foundation; either version 2 of the Chris@175: License, or (at your option) any later version. See the file Chris@175: COPYING included with this distribution for more information. Chris@175: */ Chris@175: Chris@175: #include "WritableWaveFileModel.h" Chris@175: Chris@175: #include "base/TempDirectory.h" Chris@175: #include "base/Exceptions.h" Chris@175: Chris@175: #include "fileio/WavFileWriter.h" Chris@175: #include "fileio/WavFileReader.h" Chris@175: Chris@175: #include Chris@175: Chris@175: #include Chris@175: #include Chris@175: Chris@175: WritableWaveFileModel::WritableWaveFileModel(size_t sampleRate, Chris@175: size_t channels, Chris@175: QString path) : Chris@175: m_model(0), Chris@175: m_writer(0), Chris@175: m_reader(0), Chris@175: m_sampleRate(sampleRate), Chris@175: m_channels(channels), Chris@175: m_frameCount(0) Chris@175: { Chris@175: if (path.isEmpty()) { Chris@175: try { Chris@175: QDir dir(TempDirectory::getInstance()->getPath()); Chris@175: path = dir.filePath(QString("written_%1.wav") Chris@175: .arg((intptr_t)this)); Chris@175: } catch (DirectoryCreationFailed f) { Chris@175: std::cerr << "WritableWaveFileModel: Failed to create temporary directory" << std::endl; Chris@175: return; Chris@175: } Chris@175: } Chris@175: Chris@175: m_writer = new WavFileWriter(path, sampleRate, channels); Chris@175: if (!m_writer->isOK()) { Chris@175: std::cerr << "WritableWaveFileModel: Error in creating WAV file writer: " << m_writer->getError().toStdString() << std::endl; Chris@175: delete m_writer; Chris@175: m_writer = 0; Chris@175: return; Chris@175: } Chris@175: } Chris@175: Chris@175: WritableWaveFileModel::~WritableWaveFileModel() Chris@175: { Chris@175: delete m_model; Chris@175: delete m_writer; Chris@175: delete m_reader; Chris@175: } Chris@175: Chris@175: bool Chris@175: WritableWaveFileModel::addSamples(float **samples, size_t count) Chris@175: { Chris@175: if (!m_writer) return false; Chris@175: Chris@175: if (!m_writer->writeSamples(samples, count)) { Chris@175: std::cerr << "ERROR: WritableWaveFileModel::addSamples: writer failed: " << m_writer->getError().toStdString() << std::endl; Chris@175: return false; Chris@175: } Chris@175: Chris@175: m_frameCount += count; Chris@175: Chris@175: if (!m_model) { Chris@175: Chris@176: m_reader = new WavFileReader(m_writer->getPath(), true); Chris@175: if (!m_reader->getError().isEmpty()) { Chris@175: std::cerr << "WritableWaveFileModel: Error in creating wave file reader" << std::endl; Chris@175: delete m_reader; Chris@175: m_reader = 0; Chris@175: return false; Chris@175: } Chris@175: Chris@175: m_model = new WaveFileModel(m_writer->getPath(), m_reader); Chris@175: if (!m_model->isOK()) { Chris@175: std::cerr << "WritableWaveFileModel: Error in creating wave file model" << std::endl; Chris@175: delete m_model; Chris@175: m_model = 0; Chris@175: delete m_reader; Chris@175: m_reader = 0; Chris@175: return false; Chris@175: } Chris@175: } Chris@175: Chris@175: static int updateCounter = 0; Chris@175: if (++updateCounter == 100) { Chris@175: if (m_reader) m_reader->updateFrameCount(); Chris@175: updateCounter = 0; Chris@175: } Chris@175: Chris@175: return true; Chris@175: } Chris@175: Chris@175: void Chris@175: WritableWaveFileModel::sync() Chris@175: { Chris@176: //!!! use setCompletion instead Chris@176: if (m_reader) m_reader->updateDone(); Chris@175: } Chris@175: Chris@175: bool Chris@175: WritableWaveFileModel::isOK() const Chris@175: { Chris@175: bool ok = (m_model && m_model->isOK()); Chris@175: std::cerr << "WritableWaveFileModel::isOK(): ok = " << ok << std::endl; Chris@175: return ok; Chris@175: } Chris@175: Chris@175: bool Chris@175: WritableWaveFileModel::isReady(int *completion) const Chris@175: { Chris@175: bool ready = (m_model && m_model->isReady(completion)); Chris@180: std::cerr << "WritableWaveFileModel::isReady(): ready = " << ready << ", completion = " << (completion ? *completion : -1) << std::endl; Chris@175: return ready; Chris@175: } Chris@175: Chris@175: size_t Chris@175: WritableWaveFileModel::getFrameCount() const Chris@175: { Chris@175: std::cerr << "WritableWaveFileModel::getFrameCount: count = " << m_frameCount << std::endl; Chris@175: return m_frameCount; Chris@175: } Chris@175: Chris@175: Model * Chris@175: WritableWaveFileModel::clone() const Chris@175: { Chris@175: assert(0); //!!! Chris@175: } Chris@175: Chris@175: size_t Chris@175: WritableWaveFileModel::getValues(int channel, size_t start, size_t end, Chris@175: float *buffer) const Chris@175: { Chris@175: if (!m_model) return 0; Chris@175: return m_model->getValues(channel, start, end, buffer); Chris@175: } Chris@175: Chris@175: size_t Chris@175: WritableWaveFileModel::getValues(int channel, size_t start, size_t end, Chris@175: double *buffer) const Chris@175: { Chris@175: if (!m_model) return 0; Chris@175: // std::cerr << "WritableWaveFileModel::getValues(" << channel << ", " Chris@175: // << start << ", " << end << "): calling model" << std::endl; Chris@175: return m_model->getValues(channel, start, end, buffer); Chris@175: } Chris@175: Chris@175: WritableWaveFileModel::RangeBlock Chris@175: WritableWaveFileModel::getRanges(size_t channel, size_t start, size_t end, Chris@175: size_t &blockSize) const Chris@175: { Chris@175: if (!m_model) return RangeBlock(); Chris@175: return m_model->getRanges(channel, start, end, blockSize); Chris@175: } Chris@175: Chris@175: WritableWaveFileModel::Range Chris@175: WritableWaveFileModel::getRange(size_t channel, size_t start, size_t end) const Chris@175: { Chris@175: if (!m_model) return Range(); Chris@175: return m_model->getRange(channel, start, end); Chris@175: } Chris@175: Chris@175: void Chris@175: WritableWaveFileModel::toXml(QTextStream &out, Chris@175: QString indent, Chris@175: QString extraAttributes) const Chris@175: { Chris@175: assert(0); //!!! Chris@175: } Chris@175: Chris@175: QString Chris@175: WritableWaveFileModel::toXmlString(QString indent, Chris@175: QString extraAttributes) const Chris@175: { Chris@175: assert(0); //!!! Chris@175: return ""; Chris@175: } Chris@175: