annotate data/model/WritableWaveFileModel.cpp @ 184:5a916fee6d2d

* Handle generator transforms (plugins whose channel count isn't dependent on number of audio inputs, as they have none) * Be less keen to suspend writing FFT data in spectrogram repaint -- only do it if we find we actually need to query the FFT data (i.e. we aren't repainting an area that hasn't been generated at all yet)
author Chris Cannam
date Tue, 10 Oct 2006 19:04:57 +0000
parents bd1260261412
children 89b05b679dc3
rev   line source
Chris@175 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@175 2
Chris@175 3 /*
Chris@175 4 Sonic Visualiser
Chris@175 5 An audio file viewer and annotation editor.
Chris@175 6 Centre for Digital Music, Queen Mary, University of London.
Chris@175 7 This file copyright 2006 Chris Cannam.
Chris@175 8
Chris@175 9 This program is free software; you can redistribute it and/or
Chris@175 10 modify it under the terms of the GNU General Public License as
Chris@175 11 published by the Free Software Foundation; either version 2 of the
Chris@175 12 License, or (at your option) any later version. See the file
Chris@175 13 COPYING included with this distribution for more information.
Chris@175 14 */
Chris@175 15
Chris@175 16 #include "WritableWaveFileModel.h"
Chris@175 17
Chris@175 18 #include "base/TempDirectory.h"
Chris@175 19 #include "base/Exceptions.h"
Chris@175 20
Chris@175 21 #include "fileio/WavFileWriter.h"
Chris@175 22 #include "fileio/WavFileReader.h"
Chris@175 23
Chris@175 24 #include <QDir>
Chris@175 25
Chris@175 26 #include <cassert>
Chris@175 27 #include <iostream>
Chris@175 28
Chris@175 29 WritableWaveFileModel::WritableWaveFileModel(size_t sampleRate,
Chris@175 30 size_t channels,
Chris@175 31 QString path) :
Chris@175 32 m_model(0),
Chris@175 33 m_writer(0),
Chris@175 34 m_reader(0),
Chris@175 35 m_sampleRate(sampleRate),
Chris@175 36 m_channels(channels),
Chris@175 37 m_frameCount(0)
Chris@175 38 {
Chris@175 39 if (path.isEmpty()) {
Chris@175 40 try {
Chris@175 41 QDir dir(TempDirectory::getInstance()->getPath());
Chris@175 42 path = dir.filePath(QString("written_%1.wav")
Chris@175 43 .arg((intptr_t)this));
Chris@175 44 } catch (DirectoryCreationFailed f) {
Chris@175 45 std::cerr << "WritableWaveFileModel: Failed to create temporary directory" << std::endl;
Chris@175 46 return;
Chris@175 47 }
Chris@175 48 }
Chris@175 49
Chris@175 50 m_writer = new WavFileWriter(path, sampleRate, channels);
Chris@175 51 if (!m_writer->isOK()) {
Chris@175 52 std::cerr << "WritableWaveFileModel: Error in creating WAV file writer: " << m_writer->getError().toStdString() << std::endl;
Chris@175 53 delete m_writer;
Chris@175 54 m_writer = 0;
Chris@175 55 return;
Chris@175 56 }
Chris@175 57 }
Chris@175 58
Chris@175 59 WritableWaveFileModel::~WritableWaveFileModel()
Chris@175 60 {
Chris@175 61 delete m_model;
Chris@175 62 delete m_writer;
Chris@175 63 delete m_reader;
Chris@175 64 }
Chris@175 65
Chris@175 66 bool
Chris@175 67 WritableWaveFileModel::addSamples(float **samples, size_t count)
Chris@175 68 {
Chris@175 69 if (!m_writer) return false;
Chris@175 70
Chris@175 71 if (!m_writer->writeSamples(samples, count)) {
Chris@175 72 std::cerr << "ERROR: WritableWaveFileModel::addSamples: writer failed: " << m_writer->getError().toStdString() << std::endl;
Chris@175 73 return false;
Chris@175 74 }
Chris@175 75
Chris@175 76 m_frameCount += count;
Chris@175 77
Chris@175 78 if (!m_model) {
Chris@175 79
Chris@176 80 m_reader = new WavFileReader(m_writer->getPath(), true);
Chris@175 81 if (!m_reader->getError().isEmpty()) {
Chris@175 82 std::cerr << "WritableWaveFileModel: Error in creating wave file reader" << std::endl;
Chris@175 83 delete m_reader;
Chris@175 84 m_reader = 0;
Chris@175 85 return false;
Chris@175 86 }
Chris@175 87
Chris@175 88 m_model = new WaveFileModel(m_writer->getPath(), m_reader);
Chris@175 89 if (!m_model->isOK()) {
Chris@175 90 std::cerr << "WritableWaveFileModel: Error in creating wave file model" << std::endl;
Chris@175 91 delete m_model;
Chris@175 92 m_model = 0;
Chris@175 93 delete m_reader;
Chris@175 94 m_reader = 0;
Chris@175 95 return false;
Chris@175 96 }
Chris@175 97 }
Chris@175 98
Chris@175 99 static int updateCounter = 0;
Chris@175 100 if (++updateCounter == 100) {
Chris@175 101 if (m_reader) m_reader->updateFrameCount();
Chris@175 102 updateCounter = 0;
Chris@175 103 }
Chris@175 104
Chris@175 105 return true;
Chris@175 106 }
Chris@175 107
Chris@175 108 void
Chris@175 109 WritableWaveFileModel::sync()
Chris@175 110 {
Chris@176 111 //!!! use setCompletion instead
Chris@176 112 if (m_reader) m_reader->updateDone();
Chris@175 113 }
Chris@175 114
Chris@175 115 bool
Chris@175 116 WritableWaveFileModel::isOK() const
Chris@175 117 {
Chris@175 118 bool ok = (m_model && m_model->isOK());
Chris@175 119 std::cerr << "WritableWaveFileModel::isOK(): ok = " << ok << std::endl;
Chris@175 120 return ok;
Chris@175 121 }
Chris@175 122
Chris@175 123 bool
Chris@175 124 WritableWaveFileModel::isReady(int *completion) const
Chris@175 125 {
Chris@175 126 bool ready = (m_model && m_model->isReady(completion));
Chris@180 127 std::cerr << "WritableWaveFileModel::isReady(): ready = " << ready << ", completion = " << (completion ? *completion : -1) << std::endl;
Chris@175 128 return ready;
Chris@175 129 }
Chris@175 130
Chris@175 131 size_t
Chris@175 132 WritableWaveFileModel::getFrameCount() const
Chris@175 133 {
Chris@175 134 std::cerr << "WritableWaveFileModel::getFrameCount: count = " << m_frameCount << std::endl;
Chris@175 135 return m_frameCount;
Chris@175 136 }
Chris@175 137
Chris@175 138 Model *
Chris@175 139 WritableWaveFileModel::clone() const
Chris@175 140 {
Chris@175 141 assert(0); //!!!
Chris@175 142 }
Chris@175 143
Chris@175 144 size_t
Chris@175 145 WritableWaveFileModel::getValues(int channel, size_t start, size_t end,
Chris@175 146 float *buffer) const
Chris@175 147 {
Chris@175 148 if (!m_model) return 0;
Chris@175 149 return m_model->getValues(channel, start, end, buffer);
Chris@175 150 }
Chris@175 151
Chris@175 152 size_t
Chris@175 153 WritableWaveFileModel::getValues(int channel, size_t start, size_t end,
Chris@175 154 double *buffer) const
Chris@175 155 {
Chris@175 156 if (!m_model) return 0;
Chris@175 157 // std::cerr << "WritableWaveFileModel::getValues(" << channel << ", "
Chris@175 158 // << start << ", " << end << "): calling model" << std::endl;
Chris@175 159 return m_model->getValues(channel, start, end, buffer);
Chris@175 160 }
Chris@175 161
Chris@175 162 WritableWaveFileModel::RangeBlock
Chris@175 163 WritableWaveFileModel::getRanges(size_t channel, size_t start, size_t end,
Chris@175 164 size_t &blockSize) const
Chris@175 165 {
Chris@175 166 if (!m_model) return RangeBlock();
Chris@175 167 return m_model->getRanges(channel, start, end, blockSize);
Chris@175 168 }
Chris@175 169
Chris@175 170 WritableWaveFileModel::Range
Chris@175 171 WritableWaveFileModel::getRange(size_t channel, size_t start, size_t end) const
Chris@175 172 {
Chris@175 173 if (!m_model) return Range();
Chris@175 174 return m_model->getRange(channel, start, end);
Chris@175 175 }
Chris@175 176
Chris@175 177 void
Chris@175 178 WritableWaveFileModel::toXml(QTextStream &out,
Chris@175 179 QString indent,
Chris@175 180 QString extraAttributes) const
Chris@175 181 {
Chris@175 182 assert(0); //!!!
Chris@175 183 }
Chris@175 184
Chris@175 185 QString
Chris@175 186 WritableWaveFileModel::toXmlString(QString indent,
Chris@175 187 QString extraAttributes) const
Chris@175 188 {
Chris@175 189 assert(0); //!!!
Chris@175 190 return "";
Chris@175 191 }
Chris@175 192