comparison data/fileio/WavFileWriter.cpp @ 0:fc9323a41f5a

start base : Sonic Visualiser sv1-1.0rc1
author lbajardsilogic
date Fri, 11 May 2007 09:08:14 +0000
parents
children be6d31baecb9
comparison
equal deleted inserted replaced
-1:000000000000 0:fc9323a41f5a
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 and QMUL.
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 #include "system/System.h"
21
22 #include <QFileInfo>
23
24 #include <iostream>
25
26 WavFileWriter::WavFileWriter(QString path,
27 size_t sampleRate,
28 size_t channels) :
29 m_path(path),
30 m_sampleRate(sampleRate),
31 m_channels(channels),
32 m_file(0)
33 {
34 SF_INFO fileInfo;
35 fileInfo.samplerate = m_sampleRate;
36 fileInfo.channels = m_channels;
37 fileInfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT;
38
39 m_file = sf_open(m_path.toLocal8Bit(), SFM_WRITE, &fileInfo);
40 if (!m_file) {
41 std::cerr << "WavFileWriter: Failed to open file ("
42 << sf_strerror(m_file) << ")" << std::endl;
43 m_error = QString("Failed to open audio file '%1' for writing")
44 .arg(m_path);
45 }
46 }
47
48 WavFileWriter::~WavFileWriter()
49 {
50 if (m_file) close();
51 }
52
53 bool
54 WavFileWriter::isOK() const
55 {
56 return (m_error.isEmpty());
57 }
58
59 QString
60 WavFileWriter::getError() const
61 {
62 return m_error;
63 }
64
65 bool
66 WavFileWriter::writeModel(DenseTimeValueModel *source,
67 MultiSelection *selection)
68 {
69 if (source->getChannelCount() != m_channels) {
70 std::cerr << "WavFileWriter::writeModel: Wrong number of channels ("
71 << source->getChannelCount() << " != " << m_channels << ")"
72 << std::endl;
73 m_error = QString("Failed to write model to audio file '%1'")
74 .arg(m_path);
75 return false;
76 }
77
78 if (!m_file) {
79 m_error = QString("Failed to write model to audio file '%1': File not open")
80 .arg(m_path);
81 return false;
82 }
83
84 bool ownSelection = false;
85 if (!selection) {
86 selection = new MultiSelection;
87 selection->setSelection(Selection(source->getStartFrame(),
88 source->getEndFrame()));
89 ownSelection = true;
90 }
91
92 size_t bs = 2048;
93 float *ub = new float[bs]; // uninterleaved buffer (one channel)
94 float *ib = new float[bs * m_channels]; // interleaved buffer
95
96 for (MultiSelection::SelectionList::const_iterator i =
97 selection->getSelections().begin();
98 i != selection->getSelections().end(); ++i) {
99
100 size_t f0(i->getStartFrame()), f1(i->getEndFrame());
101
102 for (size_t f = f0; f < f1; f += bs) {
103
104 size_t n = min(bs, f1 - f);
105
106 for (int c = 0; c < int(m_channels); ++c) {
107 source->getValues(c, f, f + n, ub);
108 for (size_t i = 0; i < n; ++i) {
109 ib[i * m_channels + c] = ub[i];
110 }
111 }
112
113 sf_count_t written = sf_writef_float(m_file, ib, n);
114
115 if (written < n) {
116 m_error = QString("Only wrote %1 of %2 frames at file frame %3")
117 .arg(written).arg(n).arg(f);
118 break;
119 }
120 }
121 }
122
123 delete[] ub;
124 delete[] ib;
125 if (ownSelection) delete selection;
126
127 return isOK();
128 }
129
130 bool
131 WavFileWriter::writeSamples(float **samples, size_t count)
132 {
133 if (!m_file) {
134 m_error = QString("Failed to write model to audio file '%1': File not open")
135 .arg(m_path);
136 return false;
137 }
138
139 float *b = new float[count * m_channels];
140 for (size_t i = 0; i < count; ++i) {
141 for (size_t c = 0; c < m_channels; ++c) {
142 b[i * m_channels + c] = samples[c][i];
143 }
144 }
145
146 sf_count_t written = sf_writef_float(m_file, b, count);
147
148 delete[] b;
149
150 if (written < count) {
151 m_error = QString("Only wrote %1 of %2 frames")
152 .arg(written).arg(count);
153 }
154
155 return isOK();
156 }
157
158 bool
159 WavFileWriter::close()
160 {
161 if (m_file) {
162 sf_close(m_file);
163 m_file = 0;
164 }
165 return true;
166 }
167