Mercurial > hg > svcore
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; |
