Mercurial > hg > svcore
comparison data/fileio/WavFileWriter.cpp @ 684:bcca512445f3
Provide option for WavFileWriter to write directly to target file, rather than always using a temporary; make use of it in WritableWaveFileModel so we can read from target file without having to close it first
author | Chris Cannam |
---|---|
date | Wed, 11 May 2011 11:04:35 +0100 |
parents | 920e3880f7b4 |
children | 573d45e9487b |
comparison
equal
deleted
inserted
replaced
683:f84f147572b9 | 684:bcca512445f3 |
---|---|
24 | 24 |
25 #include <iostream> | 25 #include <iostream> |
26 | 26 |
27 WavFileWriter::WavFileWriter(QString path, | 27 WavFileWriter::WavFileWriter(QString path, |
28 size_t sampleRate, | 28 size_t sampleRate, |
29 size_t channels) : | 29 size_t channels, |
30 FileWriteMode mode) : | |
30 m_path(path), | 31 m_path(path), |
31 m_sampleRate(sampleRate), | 32 m_sampleRate(sampleRate), |
32 m_channels(channels), | 33 m_channels(channels), |
33 m_temp(0), | 34 m_temp(0), |
34 m_file(0) | 35 m_file(0) |
37 fileInfo.samplerate = m_sampleRate; | 38 fileInfo.samplerate = m_sampleRate; |
38 fileInfo.channels = m_channels; | 39 fileInfo.channels = m_channels; |
39 fileInfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT; | 40 fileInfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT; |
40 | 41 |
41 try { | 42 try { |
42 m_temp = new TempWriteFile(m_path); | 43 if (mode == WriteToTemporary) { |
43 m_file = sf_open(m_temp->getTemporaryFilename().toLocal8Bit(), | 44 m_temp = new TempWriteFile(m_path); |
44 SFM_WRITE, &fileInfo); | 45 m_file = sf_open(m_temp->getTemporaryFilename().toLocal8Bit(), |
45 if (!m_file) { | 46 SFM_WRITE, &fileInfo); |
46 std::cerr << "WavFileWriter: Failed to open file (" | 47 if (!m_file) { |
47 << sf_strerror(m_file) << ")" << std::endl; | 48 std::cerr << "WavFileWriter: Failed to open file (" |
48 m_error = QString("Failed to open audio file '%1' for writing") | 49 << sf_strerror(m_file) << ")" << std::endl; |
49 .arg(m_temp->getTemporaryFilename()); | 50 m_error = QString("Failed to open audio file '%1' for writing") |
50 } | 51 .arg(m_temp->getTemporaryFilename()); |
52 } | |
53 } else { | |
54 m_file = sf_open(m_path.toLocal8Bit(), SFM_WRITE, &fileInfo); | |
55 if (!m_file) { | |
56 std::cerr << "WavFileWriter: Failed to open file (" | |
57 << sf_strerror(m_file) << ")" << std::endl; | |
58 m_error = QString("Failed to open audio file '%1' for writing") | |
59 .arg(m_path); | |
60 } | |
61 } | |
51 } catch (FileOperationFailed &f) { | 62 } catch (FileOperationFailed &f) { |
52 m_error = f.what(); | 63 m_error = f.what(); |
53 m_temp = 0; | 64 m_temp = 0; |
54 m_file = 0; | 65 m_file = 0; |
55 } | 66 } |
70 WavFileWriter::getError() const | 81 WavFileWriter::getError() const |
71 { | 82 { |
72 return m_error; | 83 return m_error; |
73 } | 84 } |
74 | 85 |
86 QString | |
87 WavFileWriter::getWriteFilename() const | |
88 { | |
89 if (m_temp) { | |
90 return m_temp->getTemporaryFilename(); | |
91 } else { | |
92 return m_path; | |
93 } | |
94 } | |
95 | |
75 bool | 96 bool |
76 WavFileWriter::writeModel(DenseTimeValueModel *source, | 97 WavFileWriter::writeModel(DenseTimeValueModel *source, |
77 MultiSelection *selection) | 98 MultiSelection *selection) |
78 { | 99 { |
79 if (!m_temp) { | |
80 m_error = QString("Failed to write model to audio file: No file open"); | |
81 return false; | |
82 } | |
83 | |
84 if (source->getChannelCount() != m_channels) { | 100 if (source->getChannelCount() != m_channels) { |
85 std::cerr << "WavFileWriter::writeModel: Wrong number of channels (" | 101 std::cerr << "WavFileWriter::writeModel: Wrong number of channels (" |
86 << source->getChannelCount() << " != " << m_channels << ")" | 102 << source->getChannelCount() << " != " << m_channels << ")" |
87 << std::endl; | 103 << std::endl; |
88 m_error = QString("Failed to write model to audio file '%1'") | 104 m_error = QString("Failed to write model to audio file '%1'") |
89 .arg(m_temp->getTemporaryFilename()); | 105 .arg(getWriteFilename()); |
90 return false; | 106 return false; |
91 } | 107 } |
92 | 108 |
93 if (!m_file) { | 109 if (!m_file) { |
94 m_error = QString("Failed to write model to audio file '%1': File not open") | 110 m_error = QString("Failed to write model to audio file '%1': File not open") |
95 .arg(m_temp->getTemporaryFilename()); | 111 .arg(getWriteFilename()); |
96 return false; | 112 return false; |
97 } | 113 } |
98 | 114 |
99 bool ownSelection = false; | 115 bool ownSelection = false; |
100 if (!selection) { | 116 if (!selection) { |
143 } | 159 } |
144 | 160 |
145 bool | 161 bool |
146 WavFileWriter::writeSamples(float **samples, size_t count) | 162 WavFileWriter::writeSamples(float **samples, size_t count) |
147 { | 163 { |
148 if (!m_temp) { | |
149 m_error = QString("Failed to write model to audio file: No file open"); | |
150 return false; | |
151 } | |
152 | |
153 if (!m_file) { | 164 if (!m_file) { |
154 m_error = QString("Failed to write model to audio file '%1': File not open") | 165 m_error = QString("Failed to write model to audio file '%1': File not open") |
155 .arg(m_temp->getTemporaryFilename()); | 166 .arg(getWriteFilename()); |
156 return false; | 167 return false; |
157 } | 168 } |
158 | 169 |
159 float *b = new float[count * m_channels]; | 170 float *b = new float[count * m_channels]; |
160 for (size_t i = 0; i < count; ++i) { | 171 for (size_t i = 0; i < count; ++i) { |
180 { | 191 { |
181 if (m_file) { | 192 if (m_file) { |
182 sf_close(m_file); | 193 sf_close(m_file); |
183 m_file = 0; | 194 m_file = 0; |
184 } | 195 } |
185 m_temp->moveToTarget(); | 196 if (m_temp) { |
186 delete m_temp; | 197 m_temp->moveToTarget(); |
187 m_temp = 0; | 198 delete m_temp; |
199 m_temp = 0; | |
200 } | |
188 return true; | 201 return true; |
189 } | 202 } |
190 | 203 |