Mercurial > hg > svcore
comparison data/fileio/WavFileWriter.cpp @ 674:920e3880f7b4
* Add TempWriteFile abstraction, use it when exporting audio to avoid clobbering existing file before export is complete
author | Chris Cannam |
---|---|
date | Tue, 29 Mar 2011 17:30:23 +0100 |
parents | 5877d68815c7 |
children | bcca512445f3 06f13a3b9e9e |
comparison
equal
deleted
inserted
replaced
673:a1ae2c1f80ab | 674:920e3880f7b4 |
---|---|
15 | 15 |
16 #include "WavFileWriter.h" | 16 #include "WavFileWriter.h" |
17 | 17 |
18 #include "model/DenseTimeValueModel.h" | 18 #include "model/DenseTimeValueModel.h" |
19 #include "base/Selection.h" | 19 #include "base/Selection.h" |
20 #include "base/TempWriteFile.h" | |
21 #include "base/Exceptions.h" | |
20 | 22 |
21 #include <QFileInfo> | 23 #include <QFileInfo> |
22 | 24 |
23 #include <iostream> | 25 #include <iostream> |
24 | 26 |
26 size_t sampleRate, | 28 size_t sampleRate, |
27 size_t channels) : | 29 size_t channels) : |
28 m_path(path), | 30 m_path(path), |
29 m_sampleRate(sampleRate), | 31 m_sampleRate(sampleRate), |
30 m_channels(channels), | 32 m_channels(channels), |
33 m_temp(0), | |
31 m_file(0) | 34 m_file(0) |
32 { | 35 { |
33 SF_INFO fileInfo; | 36 SF_INFO fileInfo; |
34 fileInfo.samplerate = m_sampleRate; | 37 fileInfo.samplerate = m_sampleRate; |
35 fileInfo.channels = m_channels; | 38 fileInfo.channels = m_channels; |
36 fileInfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT; | 39 fileInfo.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT; |
37 | 40 |
38 m_file = sf_open(m_path.toLocal8Bit(), SFM_WRITE, &fileInfo); | 41 try { |
39 if (!m_file) { | 42 m_temp = new TempWriteFile(m_path); |
40 std::cerr << "WavFileWriter: Failed to open file (" | 43 m_file = sf_open(m_temp->getTemporaryFilename().toLocal8Bit(), |
41 << sf_strerror(m_file) << ")" << std::endl; | 44 SFM_WRITE, &fileInfo); |
42 m_error = QString("Failed to open audio file '%1' for writing") | 45 if (!m_file) { |
43 .arg(m_path); | 46 std::cerr << "WavFileWriter: Failed to open file (" |
47 << sf_strerror(m_file) << ")" << std::endl; | |
48 m_error = QString("Failed to open audio file '%1' for writing") | |
49 .arg(m_temp->getTemporaryFilename()); | |
50 } | |
51 } catch (FileOperationFailed &f) { | |
52 m_error = f.what(); | |
53 m_temp = 0; | |
54 m_file = 0; | |
44 } | 55 } |
45 } | 56 } |
46 | 57 |
47 WavFileWriter::~WavFileWriter() | 58 WavFileWriter::~WavFileWriter() |
48 { | 59 { |
63 | 74 |
64 bool | 75 bool |
65 WavFileWriter::writeModel(DenseTimeValueModel *source, | 76 WavFileWriter::writeModel(DenseTimeValueModel *source, |
66 MultiSelection *selection) | 77 MultiSelection *selection) |
67 { | 78 { |
79 if (!m_temp) { | |
80 m_error = QString("Failed to write model to audio file: No file open"); | |
81 return false; | |
82 } | |
83 | |
68 if (source->getChannelCount() != m_channels) { | 84 if (source->getChannelCount() != m_channels) { |
69 std::cerr << "WavFileWriter::writeModel: Wrong number of channels (" | 85 std::cerr << "WavFileWriter::writeModel: Wrong number of channels (" |
70 << source->getChannelCount() << " != " << m_channels << ")" | 86 << source->getChannelCount() << " != " << m_channels << ")" |
71 << std::endl; | 87 << std::endl; |
72 m_error = QString("Failed to write model to audio file '%1'") | 88 m_error = QString("Failed to write model to audio file '%1'") |
73 .arg(m_path); | 89 .arg(m_temp->getTemporaryFilename()); |
74 return false; | 90 return false; |
75 } | 91 } |
76 | 92 |
77 if (!m_file) { | 93 if (!m_file) { |
78 m_error = QString("Failed to write model to audio file '%1': File not open") | 94 m_error = QString("Failed to write model to audio file '%1': File not open") |
79 .arg(m_path); | 95 .arg(m_temp->getTemporaryFilename()); |
80 return false; | 96 return false; |
81 } | 97 } |
82 | 98 |
83 bool ownSelection = false; | 99 bool ownSelection = false; |
84 if (!selection) { | 100 if (!selection) { |
127 } | 143 } |
128 | 144 |
129 bool | 145 bool |
130 WavFileWriter::writeSamples(float **samples, size_t count) | 146 WavFileWriter::writeSamples(float **samples, size_t count) |
131 { | 147 { |
148 if (!m_temp) { | |
149 m_error = QString("Failed to write model to audio file: No file open"); | |
150 return false; | |
151 } | |
152 | |
132 if (!m_file) { | 153 if (!m_file) { |
133 m_error = QString("Failed to write model to audio file '%1': File not open") | 154 m_error = QString("Failed to write model to audio file '%1': File not open") |
134 .arg(m_path); | 155 .arg(m_temp->getTemporaryFilename()); |
135 return false; | 156 return false; |
136 } | 157 } |
137 | 158 |
138 float *b = new float[count * m_channels]; | 159 float *b = new float[count * m_channels]; |
139 for (size_t i = 0; i < count; ++i) { | 160 for (size_t i = 0; i < count; ++i) { |
159 { | 180 { |
160 if (m_file) { | 181 if (m_file) { |
161 sf_close(m_file); | 182 sf_close(m_file); |
162 m_file = 0; | 183 m_file = 0; |
163 } | 184 } |
185 m_temp->moveToTarget(); | |
186 delete m_temp; | |
187 m_temp = 0; | |
164 return true; | 188 return true; |
165 } | 189 } |
166 | 190 |