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