comparison data/model/WaveFileModel.cpp @ 1100:5cbf71022679 simple-fft-model

Smooth signal flow through from file to fft model
author Chris Cannam
date Mon, 15 Jun 2015 16:02:58 +0100
parents 4d9816ba0ebe
children efea94b04d5a
comparison
equal deleted inserted replaced
1099:0c351e061945 1100:5cbf71022679
187 } 187 }
188 188
189 vector<float> 189 vector<float>
190 WaveFileModel::getData(int channel, sv_frame_t start, sv_frame_t count) const 190 WaveFileModel::getData(int channel, sv_frame_t start, sv_frame_t count) const
191 { 191 {
192 // Always read these directly from the file. 192 // Read directly from the file. This is used for e.g. audio
193 // This is used for e.g. audio playback or input to transforms. 193 // playback or input to transforms.
194 194
195 #ifdef DEBUG_WAVE_FILE_MODEL 195 #ifdef DEBUG_WAVE_FILE_MODEL
196 cout << "WaveFileModel::getData[" << this << "]: " << channel << ", " << start << ", " << count << ", " << buffer << endl; 196 cout << "WaveFileModel::getData[" << this << "]: " << channel << ", " << start << ", " << count << ", " << buffer << endl;
197 #endif 197 #endif
198
199 int channels = getChannelCount();
200
201 if (channel >= channels) {
202 cerr << "ERROR: WaveFileModel::getData: channel ("
203 << channel << ") >= channel count (" << channels << ")"
204 << endl;
205 return {};
206 }
198 207
199 if (!m_reader || !m_reader->isOK() || count == 0) { 208 if (!m_reader || !m_reader->isOK() || count == 0) {
200 return {}; 209 return {};
201 } 210 }
202 211
212 if (start >= m_startFrame) {
213 start -= m_startFrame;
214 } else {
215 if (count <= m_startFrame - start) {
216 return {};
217 } else {
218 count -= (m_startFrame - start);
219 start = 0;
220 }
221 }
222
223 vector<float> interleaved = m_reader->getInterleavedFrames(start, count);
224 if (channels == 1) return interleaved;
225
226 sv_frame_t obtained = interleaved.size() / channels;
227
228 vector<float> result(obtained, 0.f);
229
203 if (channel != -1) { 230 if (channel != -1) {
204 // get a single channel 231 // get a single channel
205 auto data = getMultiChannelData(channel, channel, start, count); 232 for (int i = 0; i < obtained; ++i) {
206 if (data.empty()) return {}; 233 result[i] = interleaved[i * channels + channel];
207 else return data[0]; 234 }
208 } 235 } else {
209 236 // channel == -1, mix down all channels
210 // channel == -1, mix down all channels 237 for (int c = 0; c < channels; ++c) {
211 238 for (int i = 0; i < obtained; ++i) {
212 auto all = getMultiChannelData(0, getChannelCount()-1, start, count); 239 result[i] += interleaved[i * channels + c];
213 if (all.empty()) return {}; 240 }
214
215 sv_frame_t n = all[0].size();
216 vector<float> result(n, 0.f);
217
218 for (int c = 0; in_range_for(all, c); ++c) {
219 for (sv_frame_t i = 0; i < n; ++i) {
220 result[i] += all[c][i];
221 } 241 }
222 } 242 }
223 243
224 return result; 244 return result;
225 } 245 }
226 246
227 vector<vector<float>> 247 vector<vector<float>>
228 WaveFileModel::getMultiChannelData(int fromchannel, int tochannel, 248 WaveFileModel::getMultiChannelData(int fromchannel, int tochannel,
229 sv_frame_t start, sv_frame_t count) const 249 sv_frame_t start, sv_frame_t count) const
230 { 250 {
251 // Read directly from the file. This is used for e.g. audio
252 // playback or input to transforms.
253
231 #ifdef DEBUG_WAVE_FILE_MODEL 254 #ifdef DEBUG_WAVE_FILE_MODEL
232 cout << "WaveFileModel::getData[" << this << "]: " << fromchannel << "," << tochannel << ", " << start << ", " << count << ", " << buffer << endl; 255 cout << "WaveFileModel::getData[" << this << "]: " << fromchannel << "," << tochannel << ", " << start << ", " << count << ", " << buffer << endl;
233 #endif 256 #endif
234 257
235 int channels = getChannelCount(); 258 int channels = getChannelCount();