comparison data/fileio/WavFileReader.cpp @ 1349:330bcc92507d 3.0-integration

Take a different approach to using libsndfile -- the _fd function doesn't work for me in this build, so use the wchar api
author Chris Cannam
date Fri, 06 Jan 2017 20:51:47 +0000
parents b3cb0edc25cd
children 75d92155fa20
comparison
equal deleted inserted replaced
1348:b3cb0edc25cd 1349:330bcc92507d
24 #include <QFileInfo> 24 #include <QFileInfo>
25 25
26 using namespace std; 26 using namespace std;
27 27
28 WavFileReader::WavFileReader(FileSource source, bool fileUpdating) : 28 WavFileReader::WavFileReader(FileSource source, bool fileUpdating) :
29 m_sndfile(0), 29 m_file(0),
30 m_source(source), 30 m_source(source),
31 m_path(source.getLocalFilename()), 31 m_path(source.getLocalFilename()),
32 m_qfile(m_path),
33 m_seekable(false), 32 m_seekable(false),
34 m_lastStart(0), 33 m_lastStart(0),
35 m_lastCount(0), 34 m_lastCount(0),
36 m_updating(fileUpdating) 35 m_updating(fileUpdating)
37 { 36 {
40 m_sampleRate = 0; 39 m_sampleRate = 0;
41 40
42 m_fileInfo.format = 0; 41 m_fileInfo.format = 0;
43 m_fileInfo.frames = 0; 42 m_fileInfo.frames = 0;
44 43
45 if (!m_qfile.open(QIODevice::ReadOnly)) { 44 #ifdef Q_OS_WIN
45 m_file = sf_wchar_open((LPCWSTR)m_path.utf16(), SFM_READ, &m_fileInfo);
46 #else
47 m_file = sf_open(m_path.toLocal8Bit(), SFM_READ, &m_fileInfo);
48 #endif
49
50 if (!m_file || (!fileUpdating && m_fileInfo.channels <= 0)) {
46 SVDEBUG << "WavFileReader::initialize: Failed to open file at \"" 51 SVDEBUG << "WavFileReader::initialize: Failed to open file at \""
47 << m_path << "\"" << endl; 52 << m_path << "\" ("
48 m_error = QString("Failed to open audio file '%1'").arg(m_path); 53 << sf_strerror(m_file) << ")" << endl;
49 return; 54
50 } 55 if (m_file) {
51
52 m_sndfile = sf_open_fd(m_qfile.handle(), SFM_READ, &m_fileInfo, false);
53
54 if (!m_sndfile || (!fileUpdating && m_fileInfo.channels <= 0)) {
55 SVDEBUG << "WavFileReader::initialize: Failed to open file at \""
56 << m_path << "\" (" << sf_strerror(m_sndfile) << ")" << endl;
57 if (m_sndfile) {
58 m_error = QString("Couldn't load audio file '%1':\n%2") 56 m_error = QString("Couldn't load audio file '%1':\n%2")
59 .arg(m_path).arg(sf_strerror(m_sndfile)); 57 .arg(m_path).arg(sf_strerror(m_file));
60 } else { 58 } else {
61 m_error = QString("Failed to open audio file '%1'").arg(m_path); 59 m_error = QString("Failed to open audio file '%1'")
60 .arg(m_path);
62 } 61 }
63 return; 62 return;
64 } 63 }
65 64
66 if (m_fileInfo.channels > 0) { 65 if (m_fileInfo.channels > 0) {
93 SVDEBUG << "WavFileReader: Filename " << m_path << ", frame count " << m_frameCount << ", channel count " << m_channelCount << ", sample rate " << m_sampleRate << ", format " << m_fileInfo.format << ", seekable " << m_fileInfo.seekable << " adjusted to " << m_seekable << endl; 92 SVDEBUG << "WavFileReader: Filename " << m_path << ", frame count " << m_frameCount << ", channel count " << m_channelCount << ", sample rate " << m_sampleRate << ", format " << m_fileInfo.format << ", seekable " << m_fileInfo.seekable << " adjusted to " << m_seekable << endl;
94 } 93 }
95 94
96 WavFileReader::~WavFileReader() 95 WavFileReader::~WavFileReader()
97 { 96 {
98 if (m_sndfile) sf_close(m_sndfile); 97 if (m_file) sf_close(m_file);
99 } 98 }
100 99
101 void 100 void
102 WavFileReader::updateFrameCount() 101 WavFileReader::updateFrameCount()
103 { 102 {
104 QMutexLocker locker(&m_mutex); 103 QMutexLocker locker(&m_mutex);
105 104
106 sv_frame_t prevCount = m_fileInfo.frames; 105 sv_frame_t prevCount = m_fileInfo.frames;
107 106
108 if (m_sndfile) { 107 if (m_file) {
109 sf_close(m_sndfile); 108 sf_close(m_file);
110 m_sndfile = sf_open_fd(m_qfile.handle(), SFM_READ, &m_fileInfo, false); 109 #ifdef Q_OS_WIN
111 if (!m_sndfile || m_fileInfo.channels <= 0) { 110 m_file = sf_wchar_open((LPCWSTR)m_path.utf16(), SFM_READ, &m_fileInfo);
112 SVCERR << "WavFileReader::updateFrameCount: Failed to reopen file at \"" << m_path << "\" (" 111 #else
113 << sf_strerror(m_sndfile) << ")" << endl; 112 m_file = sf_open(m_path.toLocal8Bit(), SFM_READ, &m_fileInfo);
113 #endif
114 if (!m_file || m_fileInfo.channels <= 0) {
115 SVDEBUG << "WavFileReader::updateFrameCount: Failed to open file at \"" << m_path << "\" ("
116 << sf_strerror(m_file) << ")" << endl;
114 } 117 }
115 } 118 }
116 119
117 // SVDEBUG << "WavFileReader::updateFrameCount: now " << m_fileInfo.frames << endl; 120 // SVDEBUG << "WavFileReader::updateFrameCount: now " << m_fileInfo.frames << endl;
118 121
144 147
145 QMutexLocker locker(&m_mutex); 148 QMutexLocker locker(&m_mutex);
146 149
147 Profiler profiler("WavFileReader::getInterleavedFrames"); 150 Profiler profiler("WavFileReader::getInterleavedFrames");
148 151
149 if (!m_sndfile || !m_channelCount) { 152 if (!m_file || !m_channelCount) {
150 return {}; 153 return {};
151 } 154 }
152 155
153 if (start >= m_fileInfo.frames) { 156 if (start >= m_fileInfo.frames) {
154 // SVDEBUG << "WavFileReader::getInterleavedFrames: " << start 157 // SVDEBUG << "WavFileReader::getInterleavedFrames: " << start
175 lastRead.partial(); 178 lastRead.partial();
176 } else { 179 } else {
177 lastRead.miss(); 180 lastRead.miss();
178 } 181 }
179 182
180 if (sf_seek(m_sndfile, start, SEEK_SET) < 0) { 183 if (sf_seek(m_file, start, SEEK_SET) < 0) {
181 return {}; 184 return {};
182 } 185 }
183 186
184 floatvec_t data; 187 floatvec_t data;
185 sv_frame_t n = count * m_fileInfo.channels; 188 sv_frame_t n = count * m_fileInfo.channels;
187 190
188 m_lastStart = start; 191 m_lastStart = start;
189 m_lastCount = count; 192 m_lastCount = count;
190 193
191 sf_count_t readCount = 0; 194 sf_count_t readCount = 0;
192 if ((readCount = sf_readf_float(m_sndfile, data.data(), count)) < 0) { 195 if ((readCount = sf_readf_float(m_file, data.data(), count)) < 0) {
193 return {}; 196 return {};
194 } 197 }
195 198
196 m_buffer = data; 199 m_buffer = data;
197 return data; 200 return data;