WavFileWriter.cpp

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2006 Chris Cannam and QMUL.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
00014 */
00015 
00016 #include "WavFileWriter.h"
00017 
00018 #include "model/DenseTimeValueModel.h"
00019 #include "base/Selection.h"
00020 
00021 #include <QFileInfo>
00022 
00023 #include <iostream>
00024 
00025 WavFileWriter::WavFileWriter(QString path,
00026                              size_t sampleRate,
00027                              size_t channels) :
00028     m_path(path),
00029     m_sampleRate(sampleRate),
00030     m_channels(channels),
00031     m_file(0)
00032 {
00033     SF_INFO fileInfo;
00034     fileInfo.samplerate = m_sampleRate;
00035     fileInfo.channels = m_channels;
00036     fileInfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT;
00037     
00038     m_file = sf_open(m_path.toLocal8Bit(), SFM_WRITE, &fileInfo);
00039     if (!m_file) {
00040         std::cerr << "WavFileWriter: Failed to open file ("
00041                   << sf_strerror(m_file) << ")" << std::endl;
00042         m_error = QString("Failed to open audio file '%1' for writing")
00043             .arg(m_path);
00044     }
00045 }
00046 
00047 WavFileWriter::~WavFileWriter()
00048 {
00049     if (m_file) close();
00050 }
00051 
00052 bool
00053 WavFileWriter::isOK() const
00054 {
00055     return (m_error.isEmpty());
00056 }
00057 
00058 QString
00059 WavFileWriter::getError() const
00060 {
00061     return m_error;
00062 }
00063 
00064 bool
00065 WavFileWriter::writeModel(DenseTimeValueModel *source,
00066                           MultiSelection *selection)
00067 {
00068     if (source->getChannelCount() != m_channels) {
00069         std::cerr << "WavFileWriter::writeModel: Wrong number of channels ("
00070                   << source->getChannelCount()  << " != " << m_channels << ")"
00071                   << std::endl;
00072         m_error = QString("Failed to write model to audio file '%1'")
00073             .arg(m_path);
00074         return false;
00075     }
00076 
00077     if (!m_file) {
00078         m_error = QString("Failed to write model to audio file '%1': File not open")
00079             .arg(m_path);
00080         return false;
00081     }
00082 
00083     bool ownSelection = false;
00084     if (!selection) {
00085         selection = new MultiSelection;
00086         selection->setSelection(Selection(source->getStartFrame(),
00087                                           source->getEndFrame()));
00088         ownSelection = true;
00089     }
00090 
00091     size_t bs = 2048;
00092     float *ub = new float[bs]; // uninterleaved buffer (one channel)
00093     float *ib = new float[bs * m_channels]; // interleaved buffer
00094 
00095     for (MultiSelection::SelectionList::iterator i =
00096              selection->getSelections().begin();
00097          i != selection->getSelections().end(); ++i) {
00098         
00099         size_t f0(i->getStartFrame()), f1(i->getEndFrame());
00100 
00101         for (size_t f = f0; f < f1; f += bs) {
00102             
00103             size_t n = std::min(bs, f1 - f);
00104 
00105             for (int c = 0; c < int(m_channels); ++c) {
00106                 source->getData(c, f, n, ub);
00107                 for (size_t i = 0; i < n; ++i) {
00108                     ib[i * m_channels + c] = ub[i];
00109                 }
00110             }       
00111 
00112             sf_count_t written = sf_writef_float(m_file, ib, n);
00113 
00114             if (written < n) {
00115                 m_error = QString("Only wrote %1 of %2 frames at file frame %3")
00116                     .arg(written).arg(n).arg(f);
00117                 break;
00118             }
00119         }
00120     }
00121 
00122     delete[] ub;
00123     delete[] ib;
00124     if (ownSelection) delete selection;
00125 
00126     return isOK();
00127 }
00128         
00129 bool
00130 WavFileWriter::writeSamples(float **samples, size_t count)
00131 {
00132     if (!m_file) {
00133         m_error = QString("Failed to write model to audio file '%1': File not open")
00134             .arg(m_path);
00135         return false;
00136     }
00137 
00138     float *b = new float[count * m_channels];
00139     for (size_t i = 0; i < count; ++i) {
00140         for (size_t c = 0; c < m_channels; ++c) {
00141             b[i * m_channels + c] = samples[c][i];
00142         }
00143     }
00144 
00145     sf_count_t written = sf_writef_float(m_file, b, count);
00146 
00147     delete[] b;
00148 
00149     if (written < count) {
00150         m_error = QString("Only wrote %1 of %2 frames")
00151             .arg(written).arg(count);
00152     }
00153 
00154     return isOK();
00155 }
00156     
00157 bool
00158 WavFileWriter::close()
00159 {
00160     if (m_file) {
00161         sf_close(m_file);
00162         m_file = 0;
00163     }
00164     return true;
00165 }
00166 

Generated on Wed Feb 20 15:45:30 2008 for SonicVisualiser by  doxygen 1.5.1