annotate data/fileio/WavFileWriter.cpp @ 167:665342c6ec57

* Add a bit of resistance to pane dragging so as to make it harder to inadvertently drag in the other axis from the one you intended
author Chris Cannam
date Fri, 22 Sep 2006 16:46:10 +0000
parents 1a42221a1522
children f8cf055dbf34
rev   line source
Chris@148 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@148 2
Chris@148 3 /*
Chris@148 4 Sonic Visualiser
Chris@148 5 An audio file viewer and annotation editor.
Chris@148 6 Centre for Digital Music, Queen Mary, University of London.
Chris@148 7 This file copyright 2006 Chris Cannam.
Chris@148 8
Chris@148 9 This program is free software; you can redistribute it and/or
Chris@148 10 modify it under the terms of the GNU General Public License as
Chris@148 11 published by the Free Software Foundation; either version 2 of the
Chris@148 12 License, or (at your option) any later version. See the file
Chris@148 13 COPYING included with this distribution for more information.
Chris@148 14 */
Chris@148 15
Chris@148 16 #include "WavFileWriter.h"
Chris@148 17
Chris@148 18 #include "model/DenseTimeValueModel.h"
Chris@148 19 #include "base/Selection.h"
Chris@148 20
Chris@148 21 #include <QFileInfo>
Chris@148 22 #include <sndfile.h>
Chris@148 23
Chris@148 24 #include <iostream>
Chris@148 25
Chris@148 26 WavFileWriter::WavFileWriter(QString path,
Chris@148 27 size_t sampleRate,
Chris@148 28 DenseTimeValueModel *source,
Chris@148 29 MultiSelection *selection) :
Chris@148 30 m_path(path),
Chris@148 31 m_sampleRate(sampleRate),
Chris@148 32 m_model(source),
Chris@148 33 m_selection(selection)
Chris@148 34 {
Chris@148 35 }
Chris@148 36
Chris@148 37 WavFileWriter::~WavFileWriter()
Chris@148 38 {
Chris@148 39 }
Chris@148 40
Chris@148 41 bool
Chris@148 42 WavFileWriter::isOK() const
Chris@148 43 {
Chris@148 44 return (m_error.isEmpty());
Chris@148 45 }
Chris@148 46
Chris@148 47 QString
Chris@148 48 WavFileWriter::getError() const
Chris@148 49 {
Chris@148 50 return m_error;
Chris@148 51 }
Chris@148 52
Chris@148 53 void
Chris@148 54 WavFileWriter::write()
Chris@148 55 {
Chris@148 56 int channels = m_model->getChannelCount();
Chris@148 57
Chris@148 58 SF_INFO fileInfo;
Chris@148 59 fileInfo.samplerate = m_sampleRate;
Chris@148 60 fileInfo.channels = channels;
Chris@148 61 fileInfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT;
Chris@148 62
Chris@148 63 SNDFILE *file = sf_open(m_path.toLocal8Bit(), SFM_WRITE, &fileInfo);
Chris@148 64 if (!file) {
Chris@148 65 std::cerr << "WavFileWriter::write: Failed to open file ("
Chris@148 66 << sf_strerror(file) << ")" << std::endl;
Chris@148 67 m_error = QString("Failed to open audio file '%1' for writing")
Chris@148 68 .arg(m_path);
Chris@148 69 return;
Chris@148 70 }
Chris@148 71
Chris@148 72 MultiSelection *selection = m_selection;
Chris@148 73
Chris@148 74 if (!m_selection) {
Chris@148 75 selection = new MultiSelection;
Chris@148 76 selection->setSelection(Selection(m_model->getStartFrame(),
Chris@148 77 m_model->getEndFrame()));
Chris@148 78 }
Chris@148 79
Chris@148 80 size_t bs = 2048;
Chris@148 81 float *ub = new float[bs]; // uninterleaved buffer (one channel)
Chris@148 82 float *ib = new float[bs * channels]; // interleaved buffer
Chris@148 83
Chris@148 84 for (MultiSelection::SelectionList::iterator i =
Chris@148 85 selection->getSelections().begin();
Chris@148 86 i != selection->getSelections().end(); ++i) {
Chris@148 87
Chris@148 88 size_t f0(i->getStartFrame()), f1(i->getEndFrame());
Chris@148 89
Chris@148 90 for (size_t f = f0; f < f1; f += bs) {
Chris@148 91
Chris@148 92 size_t n = std::min(bs, f1 - f);
Chris@148 93
Chris@148 94 for (int c = 0; c < channels; ++c) {
Chris@148 95 m_model->getValues(c, f, f + n, ub);
Chris@148 96 for (size_t i = 0; i < n; ++i) {
Chris@148 97 ib[i * channels + c] = ub[i];
Chris@148 98 }
Chris@148 99 }
Chris@148 100
Chris@148 101 sf_count_t written = sf_writef_float(file, ib, n);
Chris@148 102
Chris@148 103 if (written < n) {
Chris@148 104 m_error = QString("Only wrote %1 of %2 frames at file frame %3")
Chris@148 105 .arg(written).arg(n).arg(f);
Chris@148 106 break;
Chris@148 107 }
Chris@148 108 }
Chris@148 109 }
Chris@148 110
Chris@148 111 sf_close(file);
Chris@148 112
Chris@148 113 delete[] ub;
Chris@148 114 delete[] ib;
Chris@148 115 if (!m_selection) delete selection;
Chris@148 116 }
Chris@148 117
Chris@148 118
Chris@148 119
Chris@148 120