Mercurial > hg > svcore
diff data/fileio/WavFileWriter.cpp @ 148:1a42221a1522
* Reorganising code base. This revision will not compile.
author | Chris Cannam |
---|---|
date | Mon, 31 Jul 2006 11:49:58 +0000 |
parents | |
children | f8cf055dbf34 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data/fileio/WavFileWriter.cpp Mon Jul 31 11:49:58 2006 +0000 @@ -0,0 +1,120 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2006 Chris Cannam. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include "WavFileWriter.h" + +#include "model/DenseTimeValueModel.h" +#include "base/Selection.h" + +#include <QFileInfo> +#include <sndfile.h> + +#include <iostream> + +WavFileWriter::WavFileWriter(QString path, + size_t sampleRate, + DenseTimeValueModel *source, + MultiSelection *selection) : + m_path(path), + m_sampleRate(sampleRate), + m_model(source), + m_selection(selection) +{ +} + +WavFileWriter::~WavFileWriter() +{ +} + +bool +WavFileWriter::isOK() const +{ + return (m_error.isEmpty()); +} + +QString +WavFileWriter::getError() const +{ + return m_error; +} + +void +WavFileWriter::write() +{ + 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; + } + + MultiSelection *selection = m_selection; + + if (!m_selection) { + selection = new MultiSelection; + selection->setSelection(Selection(m_model->getStartFrame(), + m_model->getEndFrame())); + } + + size_t bs = 2048; + float *ub = new float[bs]; // uninterleaved buffer (one channel) + float *ib = new float[bs * channels]; // interleaved buffer + + for (MultiSelection::SelectionList::iterator i = + selection->getSelections().begin(); + i != selection->getSelections().end(); ++i) { + + size_t f0(i->getStartFrame()), f1(i->getEndFrame()); + + for (size_t f = f0; f < f1; f += bs) { + + size_t n = std::min(bs, f1 - f); + + for (int c = 0; c < channels; ++c) { + m_model->getValues(c, f, f + n, ub); + for (size_t i = 0; i < n; ++i) { + ib[i * channels + c] = ub[i]; + } + } + + sf_count_t written = sf_writef_float(file, ib, n); + + if (written < n) { + m_error = QString("Only wrote %1 of %2 frames at file frame %3") + .arg(written).arg(n).arg(f); + break; + } + } + } + + sf_close(file); + + delete[] ub; + delete[] ib; + if (!m_selection) delete selection; +} + + + +