Mercurial > hg > easaier-soundaccess
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 |