# HG changeset patch # User Chris Cannam # Date 1308059279 -3600 # Node ID 573d45e9487b74f289025d7c449f48b6b57bf1b5 # Parent be43b2fe68e865077366a239b7938ba92681b66c# Parent 06f13a3b9e9ee40734ac4bd30b34df80749d74d5 Merge from debug-output branch diff -r 06f13a3b9e9e -r 573d45e9487b data/fileio/WavFileWriter.cpp --- a/data/fileio/WavFileWriter.cpp Mon May 16 17:19:09 2011 +0100 +++ b/data/fileio/WavFileWriter.cpp Tue Jun 14 14:47:59 2011 +0100 @@ -26,7 +26,8 @@ WavFileWriter::WavFileWriter(QString path, size_t sampleRate, - size_t channels) : + size_t channels, + FileWriteMode mode) : m_path(path), m_sampleRate(sampleRate), m_channels(channels), @@ -39,15 +40,25 @@ fileInfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT; try { - m_temp = new TempWriteFile(m_path); - m_file = sf_open(m_temp->getTemporaryFilename().toLocal8Bit(), - SFM_WRITE, &fileInfo); - if (!m_file) { - std::cerr << "WavFileWriter: Failed to open file (" - << sf_strerror(m_file) << ")" << std::endl; - m_error = QString("Failed to open audio file '%1' for writing") - .arg(m_temp->getTemporaryFilename()); - } + if (mode == WriteToTemporary) { + m_temp = new TempWriteFile(m_path); + m_file = sf_open(m_temp->getTemporaryFilename().toLocal8Bit(), + SFM_WRITE, &fileInfo); + if (!m_file) { + std::cerr << "WavFileWriter: Failed to open file (" + << sf_strerror(m_file) << ")" << std::endl; + m_error = QString("Failed to open audio file '%1' for writing") + .arg(m_temp->getTemporaryFilename()); + } + } else { + m_file = sf_open(m_path.toLocal8Bit(), SFM_WRITE, &fileInfo); + if (!m_file) { + std::cerr << "WavFileWriter: Failed to open file (" + << sf_strerror(m_file) << ")" << std::endl; + m_error = QString("Failed to open audio file '%1' for writing") + .arg(m_path); + } + } } catch (FileOperationFailed &f) { m_error = f.what(); m_temp = 0; @@ -72,27 +83,32 @@ return m_error; } +QString +WavFileWriter::getWriteFilename() const +{ + if (m_temp) { + return m_temp->getTemporaryFilename(); + } else { + return m_path; + } +} + bool WavFileWriter::writeModel(DenseTimeValueModel *source, MultiSelection *selection) { - if (!m_temp) { - m_error = QString("Failed to write model to audio file: No file open"); - return false; - } - if (source->getChannelCount() != m_channels) { DEBUG << "WavFileWriter::writeModel: Wrong number of channels (" << source->getChannelCount() << " != " << m_channels << ")" << endl; m_error = QString("Failed to write model to audio file '%1'") - .arg(m_temp->getTemporaryFilename()); + .arg(getWriteFilename()); return false; } if (!m_file) { m_error = QString("Failed to write model to audio file '%1': File not open") - .arg(m_temp->getTemporaryFilename()); + .arg(getWriteFilename()); return false; } @@ -145,14 +161,9 @@ bool WavFileWriter::writeSamples(float **samples, size_t count) { - if (!m_temp) { - m_error = QString("Failed to write model to audio file: No file open"); - return false; - } - if (!m_file) { m_error = QString("Failed to write model to audio file '%1': File not open") - .arg(m_temp->getTemporaryFilename()); + .arg(getWriteFilename()); return false; } @@ -182,9 +193,11 @@ sf_close(m_file); m_file = 0; } - m_temp->moveToTarget(); - delete m_temp; - m_temp = 0; + if (m_temp) { + m_temp->moveToTarget(); + delete m_temp; + m_temp = 0; + } return true; } diff -r 06f13a3b9e9e -r 573d45e9487b data/fileio/WavFileWriter.h --- a/data/fileio/WavFileWriter.h Mon May 16 17:19:09 2011 +0100 +++ b/data/fileio/WavFileWriter.h Tue Jun 14 14:47:59 2011 +0100 @@ -27,7 +27,25 @@ class WavFileWriter { public: - WavFileWriter(QString path, size_t sampleRate, size_t channels); + /** + * Specify the method used to open the destination file. + * + * If WriteToTemporary, the destination will be opened as a + * temporary file which is moved to the target location when the + * WavFileWriter is closed or deleted (to avoid clobbering an + * existing file with a partially written replacement). + * + * If WriteToTarget, the target file will be opened directly + * (necessary when e.g. doing a series of incremental writes to a + * file while keeping it open for reading). + */ + enum FileWriteMode { + WriteToTemporary, + WriteToTarget + }; + + WavFileWriter(QString path, size_t sampleRate, size_t channels, + FileWriteMode mode); virtual ~WavFileWriter(); bool isOK() const; @@ -50,6 +68,8 @@ TempWriteFile *m_temp; SNDFILE *m_file; QString m_error; + + QString getWriteFilename() const; }; diff -r 06f13a3b9e9e -r 573d45e9487b data/model/WritableWaveFileModel.cpp --- a/data/model/WritableWaveFileModel.cpp Mon May 16 17:19:09 2011 +0100 +++ b/data/model/WritableWaveFileModel.cpp Tue Jun 14 14:47:59 2011 +0100 @@ -52,7 +52,10 @@ } } - m_writer = new WavFileWriter(path, sampleRate, channels); + // Write directly to the target file, so that we can do + // incremental writes and concurrent reads + m_writer = new WavFileWriter(path, sampleRate, channels, + WavFileWriter::WriteToTarget); if (!m_writer->isOK()) { std::cerr << "WritableWaveFileModel: Error in creating WAV file writer: " << m_writer->getError() << std::endl; delete m_writer; diff -r 06f13a3b9e9e -r 573d45e9487b rdf/RDFTransformFactory.cpp --- a/rdf/RDFTransformFactory.cpp Mon May 16 17:19:09 2011 +0100 +++ b/rdf/RDFTransformFactory.cpp Tue Jun 14 14:47:59 2011 +0100 @@ -272,8 +272,9 @@ } else if (optional == "block_size") { transform.setBlockSize(v.value.toUInt()); } else if (optional == "window_type") { - DEBUG << "NOTE: can't handle window type yet (value is \"" - << v.value << "\")" << endl; + transform.setWindowType + (Window::getTypeForName + (v.value.toLower().toStdString())); } else if (optional == "sample_rate") { transform.setSampleRate(v.value.toFloat()); } else if (optional == "start") { diff -r 06f13a3b9e9e -r 573d45e9487b transform/RealTimeEffectModelTransformer.cpp --- a/transform/RealTimeEffectModelTransformer.cpp Mon May 16 17:19:09 2011 +0100 +++ b/transform/RealTimeEffectModelTransformer.cpp Tue Jun 14 14:47:59 2011 +0100 @@ -179,7 +179,7 @@ long completion = (((blockFrame - contextStart) / blockSize) * 99) / - ((contextDuration) / blockSize); + (1 + ((contextDuration) / blockSize)); long got = 0;