# HG changeset patch # User Chris Cannam # Date 1159869997 0 # Node ID f8cf055dbf34c9e62e8b9b82614fc5782566599c # Parent 058a82e8bc3cdb5893772bf6286be448d20d1742 * Restructure WavFileWriter a bit to permit writing from raw data as well as from an existing model diff -r 058a82e8bc3c -r f8cf055dbf34 data/fileio/WavFileWriter.cpp --- a/data/fileio/WavFileWriter.cpp Wed Sep 27 20:52:48 2006 +0000 +++ b/data/fileio/WavFileWriter.cpp Tue Oct 03 10:06:37 2006 +0000 @@ -19,23 +19,34 @@ #include "base/Selection.h" #include -#include #include WavFileWriter::WavFileWriter(QString path, size_t sampleRate, - DenseTimeValueModel *source, - MultiSelection *selection) : + size_t channels) : m_path(path), m_sampleRate(sampleRate), - m_model(source), - m_selection(selection) + m_channels(channels), + m_file(0) { + SF_INFO fileInfo; + fileInfo.samplerate = m_sampleRate; + fileInfo.channels = m_channels; + fileInfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT; + + 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); + } } WavFileWriter::~WavFileWriter() { + if (m_file) close(); } bool @@ -50,36 +61,36 @@ return m_error; } -void -WavFileWriter::write() +bool +WavFileWriter::writeModel(DenseTimeValueModel *source, + MultiSelection *selection) { - int channels = m_model->getChannelCount(); - - SF_INFO fileInfo; - fileInfo.samplerate = m_sampleRate; - fileInfo.channels = channels; - fileInfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT; - - SNDFILE *file = sf_open(m_path.toLocal8Bit(), SFM_WRITE, &fileInfo); - if (!file) { - std::cerr << "WavFileWriter::write: Failed to open file (" - << sf_strerror(file) << ")" << std::endl; - m_error = QString("Failed to open audio file '%1' for writing") - .arg(m_path); - return; + if (source->getChannelCount() != m_channels) { + std::cerr << "WavFileWriter::writeModel: Wrong number of channels (" + << source->getChannelCount() << " != " << m_channels << ")" + << std::endl; + m_error = QString("Failed to write model to audio file '%1'") + .arg(m_path); + return false; } - MultiSelection *selection = m_selection; + if (!m_file) { + m_error = QString("Failed to write model to audio file '%1': File not open") + .arg(m_path); + return false; + } - if (!m_selection) { + bool ownSelection = false; + if (!selection) { selection = new MultiSelection; - selection->setSelection(Selection(m_model->getStartFrame(), - m_model->getEndFrame())); + selection->setSelection(Selection(source->getStartFrame(), + source->getEndFrame())); + ownSelection = true; } size_t bs = 2048; float *ub = new float[bs]; // uninterleaved buffer (one channel) - float *ib = new float[bs * channels]; // interleaved buffer + float *ib = new float[bs * m_channels]; // interleaved buffer for (MultiSelection::SelectionList::iterator i = selection->getSelections().begin(); @@ -91,14 +102,14 @@ size_t n = std::min(bs, f1 - f); - for (int c = 0; c < channels; ++c) { - m_model->getValues(c, f, f + n, ub); + for (int c = 0; c < int(m_channels); ++c) { + source->getValues(c, f, f + n, ub); for (size_t i = 0; i < n; ++i) { - ib[i * channels + c] = ub[i]; + ib[i * m_channels + c] = ub[i]; } } - sf_count_t written = sf_writef_float(file, ib, n); + sf_count_t written = sf_writef_float(m_file, ib, n); if (written < n) { m_error = QString("Only wrote %1 of %2 frames at file frame %3") @@ -108,13 +119,48 @@ } } - sf_close(file); - delete[] ub; delete[] ib; - if (!m_selection) delete selection; + if (ownSelection) delete selection; + + return isOK(); +} + +bool +WavFileWriter::writeSamples(float **samples, size_t count) +{ + if (!m_file) { + m_error = QString("Failed to write model to audio file '%1': File not open") + .arg(m_path); + return false; + } + + float *b = new float[count * m_channels]; + for (size_t i = 0; i < count; ++i) { + for (size_t c = 0; c < m_channels; ++c) { + b[i * m_channels + c] = samples[c][i]; + } + } + + sf_count_t written = sf_writef_float(m_file, b, count); + + delete[] b; + + if (written < count) { + m_error = QString("Only wrote %1 of %2 frames") + .arg(written).arg(count); + } + + return isOK(); +} + +bool +WavFileWriter::close() +{ + if (m_file) { + sf_close(m_file); + m_file = 0; + } + return true; } - - - diff -r 058a82e8bc3c -r f8cf055dbf34 data/fileio/WavFileWriter.h --- a/data/fileio/WavFileWriter.h Wed Sep 27 20:52:48 2006 +0000 +++ b/data/fileio/WavFileWriter.h Tue Oct 03 10:06:37 2006 +0000 @@ -18,28 +18,33 @@ #include +#include + class DenseTimeValueModel; class MultiSelection; class WavFileWriter { public: - WavFileWriter(QString path, size_t sampleRate, - DenseTimeValueModel *source, - MultiSelection *selection); + WavFileWriter(QString path, size_t sampleRate, size_t channels); virtual ~WavFileWriter(); bool isOK() const; virtual QString getError() const; - void write(); + bool writeModel(DenseTimeValueModel *source, + MultiSelection *selection = 0); + + bool writeSamples(float **samples, size_t count); // count per channel + + bool close(); protected: QString m_path; size_t m_sampleRate; - DenseTimeValueModel *m_model; - MultiSelection *m_selection; + size_t m_channels; + SNDFILE *m_file; QString m_error; }; diff -r 058a82e8bc3c -r f8cf055dbf34 system/Init.cpp --- a/system/Init.cpp Wed Sep 27 20:52:48 2006 +0000 +++ b/system/Init.cpp Tue Oct 03 10:06:37 2006 +0000 @@ -29,7 +29,7 @@ char errstr[256]; XGetErrorText(dpy, err->error_code, errstr, 256); if (err->error_code != BadWindow) { - std::cerr << "waveform: X Error: " + std::cerr << "Sonic Visualiser: X Error: " << errstr << " " << int(err->error_code) << "\nin major opcode: " << int(err->request_code) << std::endl;