00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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];
00093 float *ib = new float[bs * m_channels];
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