00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "WritableWaveFileModel.h"
00017
00018 #include "base/TempDirectory.h"
00019 #include "base/Exceptions.h"
00020
00021 #include "fileio/WavFileWriter.h"
00022 #include "fileio/WavFileReader.h"
00023
00024 #include <QDir>
00025 #include <QTextStream>
00026
00027 #include <cassert>
00028 #include <iostream>
00029
00030
00031
00032 WritableWaveFileModel::WritableWaveFileModel(size_t sampleRate,
00033 size_t channels,
00034 QString path) :
00035 m_model(0),
00036 m_writer(0),
00037 m_reader(0),
00038 m_sampleRate(sampleRate),
00039 m_channels(channels),
00040 m_frameCount(0),
00041 m_startFrame(0),
00042 m_completion(0)
00043 {
00044 if (path.isEmpty()) {
00045 try {
00046 QDir dir(TempDirectory::getInstance()->getPath());
00047 path = dir.filePath(QString("written_%1.wav")
00048 .arg((intptr_t)this));
00049 } catch (DirectoryCreationFailed f) {
00050 std::cerr << "WritableWaveFileModel: Failed to create temporary directory" << std::endl;
00051 return;
00052 }
00053 }
00054
00055 m_writer = new WavFileWriter(path, sampleRate, channels);
00056 if (!m_writer->isOK()) {
00057 std::cerr << "WritableWaveFileModel: Error in creating WAV file writer: " << m_writer->getError().toStdString() << std::endl;
00058 delete m_writer;
00059 m_writer = 0;
00060 return;
00061 }
00062
00063 FileSource source(m_writer->getPath());
00064
00065 m_reader = new WavFileReader(source, true);
00066 if (!m_reader->getError().isEmpty()) {
00067 std::cerr << "WritableWaveFileModel: Error in creating wave file reader" << std::endl;
00068 delete m_reader;
00069 m_reader = 0;
00070 return;
00071 }
00072
00073 m_model = new WaveFileModel(source, m_reader);
00074 if (!m_model->isOK()) {
00075 std::cerr << "WritableWaveFileModel: Error in creating wave file model" << std::endl;
00076 delete m_model;
00077 m_model = 0;
00078 delete m_reader;
00079 m_reader = 0;
00080 return;
00081 }
00082 m_model->setStartFrame(m_startFrame);
00083
00084 connect(m_model, SIGNAL(modelChanged()), this, SIGNAL(modelChanged()));
00085 connect(m_model, SIGNAL(modelChanged(size_t, size_t)),
00086 this, SIGNAL(modelChanged(size_t, size_t)));
00087 }
00088
00089 WritableWaveFileModel::~WritableWaveFileModel()
00090 {
00091 delete m_model;
00092 delete m_writer;
00093 delete m_reader;
00094 }
00095
00096 void
00097 WritableWaveFileModel::setStartFrame(size_t startFrame)
00098 {
00099 m_startFrame = startFrame;
00100 if (m_model) m_model->setStartFrame(startFrame);
00101 }
00102
00103 bool
00104 WritableWaveFileModel::addSamples(float **samples, size_t count)
00105 {
00106 if (!m_writer) return false;
00107
00108 #ifdef DEBUG_WRITABLE_WAVE_FILE_MODEL
00109
00110 #endif
00111
00112 if (!m_writer->writeSamples(samples, count)) {
00113 std::cerr << "ERROR: WritableWaveFileModel::addSamples: writer failed: " << m_writer->getError().toStdString() << std::endl;
00114 return false;
00115 }
00116
00117 m_frameCount += count;
00118
00119 static int updateCounter = 0;
00120
00121 if (m_reader && m_reader->getChannelCount() == 0) {
00122 #ifdef DEBUG_WRITABLE_WAVE_FILE_MODEL
00123 std::cerr << "WritableWaveFileModel::addSamples(" << count << "): calling updateFrameCount (initial)" << std::endl;
00124 #endif
00125 m_reader->updateFrameCount();
00126 } else if (++updateCounter == 100) {
00127 #ifdef DEBUG_WRITABLE_WAVE_FILE_MODEL
00128 std::cerr << "WritableWaveFileModel::addSamples(" << count << "): calling updateFrameCount (periodic)" << std::endl;
00129 #endif
00130 if (m_reader) m_reader->updateFrameCount();
00131 updateCounter = 0;
00132 }
00133
00134 return true;
00135 }
00136
00137 bool
00138 WritableWaveFileModel::isOK() const
00139 {
00140 bool ok = (m_writer && m_writer->isOK());
00141
00142 return ok;
00143 }
00144
00145 bool
00146 WritableWaveFileModel::isReady(int *completion) const
00147 {
00148 if (completion) *completion = m_completion;
00149 return (m_completion == 100);
00150 }
00151
00152 void
00153 WritableWaveFileModel::setCompletion(int completion)
00154 {
00155 m_completion = completion;
00156 if (completion == 100) {
00157 if (m_reader) m_reader->updateDone();
00158 }
00159 }
00160
00161 size_t
00162 WritableWaveFileModel::getFrameCount() const
00163 {
00164
00165 return m_frameCount;
00166 }
00167
00168 Model *
00169 WritableWaveFileModel::clone() const
00170 {
00171 assert(0);
00172 return 0;
00173 }
00174
00175 size_t
00176 WritableWaveFileModel::getData(int channel, size_t start, size_t count,
00177 float *buffer) const
00178 {
00179 if (!m_model || m_model->getChannelCount() == 0) return 0;
00180 return m_model->getData(channel, start, count, buffer);
00181 }
00182
00183 size_t
00184 WritableWaveFileModel::getData(int channel, size_t start, size_t count,
00185 double *buffer) const
00186 {
00187 if (!m_model || m_model->getChannelCount() == 0) return 0;
00188 return m_model->getData(channel, start, count, buffer);
00189 }
00190
00191 size_t
00192 WritableWaveFileModel::getData(size_t fromchannel, size_t tochannel,
00193 size_t start, size_t count,
00194 float **buffers) const
00195 {
00196 if (!m_model || m_model->getChannelCount() == 0) return 0;
00197 return m_model->getData(fromchannel, tochannel, start, count, buffers);
00198 }
00199
00200 size_t
00201 WritableWaveFileModel::getSummaryBlockSize(size_t desired) const
00202 {
00203 if (!m_model) return desired;
00204 return m_model->getSummaryBlockSize(desired);
00205 }
00206
00207 void
00208 WritableWaveFileModel::getSummaries(size_t channel, size_t start, size_t count,
00209 RangeBlock &ranges,
00210 size_t &blockSize) const
00211 {
00212 ranges.clear();
00213 if (!m_model || m_model->getChannelCount() == 0) return;
00214 m_model->getSummaries(channel, start, count, ranges, blockSize);
00215 }
00216
00217 WritableWaveFileModel::Range
00218 WritableWaveFileModel::getSummary(size_t channel, size_t start, size_t count) const
00219 {
00220 if (!m_model || m_model->getChannelCount() == 0) return Range();
00221 return m_model->getSummary(channel, start, count);
00222 }
00223
00224 void
00225 WritableWaveFileModel::toXml(QTextStream &out,
00226 QString indent,
00227 QString extraAttributes) const
00228 {
00229
00230
00231
00232
00233
00234 Model::toXml
00235 (out, indent,
00236 QString("type=\"writablewavefile\" file=\"%1\" channels=\"%2\" %3")
00237 .arg(m_writer->getPath()).arg(m_model->getChannelCount()).arg(extraAttributes));
00238 }
00239