Mercurial > hg > svcore
diff data/fileio/WavFileWriter.cpp @ 1527:710e6250a401 zoom
Merge from default branch
author | Chris Cannam |
---|---|
date | Mon, 17 Sep 2018 13:51:14 +0100 |
parents | 8988b27ebf38 |
children | 70e172e6cc59 |
line wrap: on
line diff
--- a/data/fileio/WavFileWriter.cpp Mon Dec 12 15:18:52 2016 +0000 +++ b/data/fileio/WavFileWriter.cpp Mon Sep 17 13:51:14 2018 +0100 @@ -19,16 +19,21 @@ #include "base/Selection.h" #include "base/TempWriteFile.h" #include "base/Exceptions.h" +#include "base/Debug.h" + +#include <bqvec/Allocators.h> +#include <bqvec/VectorOps.h> #include <QFileInfo> #include <iostream> #include <cmath> +#include <string> using namespace std; WavFileWriter::WavFileWriter(QString path, - sv_samplerate_t sampleRate, + sv_samplerate_t sampleRate, int channels, FileWriteMode mode) : m_path(path), @@ -41,7 +46,7 @@ int fileRate = int(round(m_sampleRate)); if (m_sampleRate != sv_samplerate_t(fileRate)) { - cerr << "WavFileWriter: WARNING: Non-integer sample rate " + SVCERR << "WavFileWriter: WARNING: Non-integer sample rate " << m_sampleRate << " presented, rounding to " << fileRate << endl; } @@ -50,25 +55,27 @@ fileInfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT; try { + QString writePath = m_path; if (mode == WriteToTemporary) { m_temp = new TempWriteFile(m_path); - m_file = sf_open(m_temp->getTemporaryFilename().toLocal8Bit(), - SFM_WRITE, &fileInfo); - if (!m_file) { - cerr << "WavFileWriter: Failed to open file (" - << sf_strerror(m_file) << ")" << endl; - m_error = QString("Failed to open audio file '%1' for writing") - .arg(m_temp->getTemporaryFilename()); + writePath = m_temp->getTemporaryFilename(); + } +#ifdef Q_OS_WIN + m_file = sf_wchar_open((LPCWSTR)writePath.utf16(), SFM_WRITE, &fileInfo); +#else + m_file = sf_open(writePath.toLocal8Bit(), SFM_WRITE, &fileInfo); +#endif + if (!m_file) { + SVCERR << "WavFileWriter: Failed to create float-WAV file of " + << m_channels << " channels at rate " << fileRate << " (" + << sf_strerror(m_file) << ")" << endl; + m_error = QString("Failed to open audio file '%1' for writing") + .arg(writePath); + if (m_temp) { + delete m_temp; + m_temp = 0; } - } else { - m_file = sf_open(m_path.toLocal8Bit(), SFM_WRITE, &fileInfo); - if (!m_file) { - cerr << "WavFileWriter: Failed to open file (" - << sf_strerror(m_file) << ")" << 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; @@ -119,59 +126,59 @@ if (!m_file) { m_error = QString("Failed to write model to audio file '%1': File not open") .arg(getWriteFilename()); - return false; + return false; } bool ownSelection = false; if (!selection) { - selection = new MultiSelection; - selection->setSelection(Selection(source->getStartFrame(), - source->getEndFrame())); + selection = new MultiSelection; + selection->setSelection(Selection(source->getStartFrame(), + source->getEndFrame())); ownSelection = true; } sv_frame_t bs = 2048; for (MultiSelection::SelectionList::iterator i = - selection->getSelections().begin(); - i != selection->getSelections().end(); ++i) { - - sv_frame_t f0(i->getStartFrame()), f1(i->getEndFrame()); + selection->getSelections().begin(); + i != selection->getSelections().end(); ++i) { + + sv_frame_t f0(i->getStartFrame()), f1(i->getEndFrame()); - for (sv_frame_t f = f0; f < f1; f += bs) { - - sv_frame_t n = min(bs, f1 - f); - vector<float> interleaved(n * m_channels, 0.f); + for (sv_frame_t f = f0; f < f1; f += bs) { + + sv_frame_t n = min(bs, f1 - f); + floatvec_t interleaved(n * m_channels, 0.f); - for (int c = 0; c < int(m_channels); ++c) { - vector<float> chanbuf = source->getData(c, f, n); - for (int i = 0; in_range_for(chanbuf, i); ++i) { - interleaved[i * m_channels + c] = chanbuf[i]; - } - } + for (int c = 0; c < int(m_channels); ++c) { + auto chanbuf = source->getData(c, f, n); + for (int i = 0; in_range_for(chanbuf, i); ++i) { + interleaved[i * m_channels + c] = chanbuf[i]; + } + } - sf_count_t written = sf_writef_float(m_file, interleaved.data(), n); + sf_count_t written = sf_writef_float(m_file, interleaved.data(), n); - if (written < n) { - m_error = QString("Only wrote %1 of %2 frames at file frame %3") - .arg(written).arg(n).arg(f); - break; - } - } + if (written < n) { + m_error = QString("Only wrote %1 of %2 frames at file frame %3") + .arg(written).arg(n).arg(f); + break; + } + } } if (ownSelection) delete selection; return isOK(); } - + bool -WavFileWriter::writeSamples(float **samples, sv_frame_t count) +WavFileWriter::writeSamples(const float *const *samples, sv_frame_t count) { if (!m_file) { m_error = QString("Failed to write model to audio file '%1': File not open") .arg(getWriteFilename()); - return false; + return false; } float *b = new float[count * m_channels]; @@ -192,7 +199,20 @@ return isOK(); } - + +bool +WavFileWriter::putInterleavedFrames(const floatvec_t &frames) +{ + sv_frame_t count = frames.size() / m_channels; + float **samples = + breakfastquay::allocate_channels<float>(m_channels, count); + breakfastquay::v_deinterleave + (samples, frames.data(), m_channels, int(count)); + bool result = writeSamples(samples, count); + breakfastquay::deallocate_channels(samples, m_channels); + return result; +} + bool WavFileWriter::close() {