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