comparison data/fileio/WavFileReader.cpp @ 0:fc9323a41f5a

start base : Sonic Visualiser sv1-1.0rc1
author lbajardsilogic
date Fri, 11 May 2007 09:08:14 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:fc9323a41f5a
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Sonic Visualiser
5 An audio file viewer and annotation editor.
6 Centre for Digital Music, Queen Mary, University of London.
7 This file copyright 2006 Chris Cannam and QMUL.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version. See the file
13 COPYING included with this distribution for more information.
14 */
15
16 #include "WavFileReader.h"
17
18 #include <iostream>
19
20 #include <QMutexLocker>
21
22 WavFileReader::WavFileReader(QString path, bool fileUpdating) :
23 m_file(0),
24 m_path(path),
25 m_buffer(0),
26 m_bufsiz(0),
27 m_lastStart(0),
28 m_lastCount(0),
29 m_updating(fileUpdating)
30 {
31 m_frameCount = 0;
32 m_channelCount = 0;
33 m_sampleRate = 0;
34
35 m_fileInfo.format = 0;
36 m_fileInfo.frames = 0;
37 m_file = sf_open(m_path.toLocal8Bit(), SFM_READ, &m_fileInfo);
38
39 if (!m_file || (!fileUpdating && m_fileInfo.channels <= 0)) {
40 std::cerr << "WavFileReader::initialize: Failed to open file ("
41 << sf_strerror(m_file) << ")" << std::endl;
42
43 if (m_file) {
44 m_error = QString("Couldn't load audio file '%1':\n%2")
45 .arg(m_path).arg(sf_strerror(m_file));
46 } else {
47 m_error = QString("Failed to open audio file '%1'")
48 .arg(m_path);
49 }
50 return;
51 }
52
53 if (m_fileInfo.channels > 0) {
54 m_frameCount = m_fileInfo.frames;
55 m_channelCount = m_fileInfo.channels;
56 m_sampleRate = m_fileInfo.samplerate;
57 }
58
59 // std::cerr << "WavFileReader: Frame count " << m_frameCount << ", channel count " << m_channelCount << ", sample rate " << m_sampleRate << std::endl;
60
61 }
62
63 WavFileReader::~WavFileReader()
64 {
65 if (m_file) sf_close(m_file);
66 }
67
68 void
69 WavFileReader::updateFrameCount()
70 {
71 QMutexLocker locker(&m_mutex);
72
73 size_t prevCount = m_fileInfo.frames;
74
75 if (m_file) {
76 sf_close(m_file);
77 m_file = sf_open(m_path.toLocal8Bit(), SFM_READ, &m_fileInfo);
78 if (!m_file || m_fileInfo.channels <= 0) {
79 std::cerr << "WavFileReader::updateFrameCount: Failed to open file ("
80 << sf_strerror(m_file) << ")" << std::endl;
81 }
82 }
83
84 // std::cerr << "WavFileReader::updateFrameCount: now " << m_fileInfo.frames << std::endl;
85
86 m_frameCount = m_fileInfo.frames;
87
88 if (m_channelCount == 0) {
89 m_channelCount = m_fileInfo.channels;
90 m_sampleRate = m_fileInfo.samplerate;
91 }
92
93 if (m_frameCount != prevCount) {
94 // std::cerr << "frameCountChanged" << std::endl;
95 emit frameCountChanged();
96 }
97 }
98
99 void
100 WavFileReader::updateDone()
101 {
102 updateFrameCount();
103 m_updating = false;
104 }
105
106 void
107 WavFileReader::getInterleavedFrames(size_t start, size_t count,
108 SampleBlock &results) const
109 {
110 if (count == 0) return;
111 results.clear();
112
113 QMutexLocker locker(&m_mutex);
114
115 if (!m_file || !m_channelCount) {
116 return;
117 }
118
119 if ((long)start >= m_fileInfo.frames) {
120 // std::cerr << "WavFileReader::getInterleavedFrames: " << start
121 // << " > " << m_fileInfo.frames << std::endl;
122 return;
123 }
124
125 if (long(start + count) > m_fileInfo.frames) {
126 count = m_fileInfo.frames - start;
127 }
128
129 sf_count_t readCount = 0;
130
131 if (start != m_lastStart || count != m_lastCount) {
132
133 if (sf_seek(m_file, start, SEEK_SET) < 0) {
134 // std::cerr << "sf_seek failed" << std::endl;
135 return;
136 }
137
138 if (count * m_fileInfo.channels > m_bufsiz) {
139 // std::cerr << "WavFileReader: Reallocating buffer for " << count
140 // << " frames, " << m_fileInfo.channels << " channels: "
141 // << m_bufsiz << " floats" << std::endl;
142 m_bufsiz = count * m_fileInfo.channels;
143 delete[] m_buffer;
144 m_buffer = new float[m_bufsiz];
145 }
146
147 if ((readCount = sf_readf_float(m_file, m_buffer, count)) < 0) {
148 // std::cerr << "sf_readf_float failed" << std::endl;
149 return;
150 }
151
152 m_lastStart = start;
153 m_lastCount = readCount;
154 }
155
156 for (size_t i = 0; i < count * m_fileInfo.channels; ++i) {
157 if (i >= m_bufsiz) {
158 std::cerr << "INTERNAL ERROR: WavFileReader::getInterleavedFrames: " << i << " >= " << m_bufsiz << std::endl;
159 }
160 results.push_back(m_buffer[i]);
161 }
162
163 return;
164 }
165
166 void
167 WavFileReader::getSupportedExtensions(std::set<QString> &extensions)
168 {
169 int count;
170
171 if (sf_command(0, SFC_GET_FORMAT_MAJOR_COUNT, &count, sizeof(count))) {
172 extensions.insert("wav");
173 extensions.insert("aiff");
174 extensions.insert("aif");
175 return;
176 }
177
178 SF_FORMAT_INFO info;
179 for (int i = 0; i < count; ++i) {
180 info.format = i;
181 if (!sf_command(0, SFC_GET_FORMAT_MAJOR, &info, sizeof(info))) {
182 extensions.insert(info.extension);
183 }
184 }
185 }