Mercurial > hg > svcore
comparison data/fileio/CodedAudioFileReader.cpp @ 1038:cc27f35aa75c cxx11
Introducing the signed 64-bit frame index type, and fixing build failures from inclusion of -Wconversion with -Werror. Not finished yet.
author | Chris Cannam |
---|---|
date | Tue, 03 Mar 2015 15:18:24 +0000 |
parents | d03b3d956358 |
children | a1cd5abcb38b |
comparison
equal
deleted
inserted
replaced
1037:bf0e5944289b | 1038:cc27f35aa75c |
---|---|
111 if (m_fileRate != m_sampleRate) { | 111 if (m_fileRate != m_sampleRate) { |
112 SVDEBUG << "CodedAudioFileReader: resampling " << m_fileRate << " -> " << m_sampleRate << endl; | 112 SVDEBUG << "CodedAudioFileReader: resampling " << m_fileRate << " -> " << m_sampleRate << endl; |
113 m_resampler = new Resampler(Resampler::FastestTolerable, | 113 m_resampler = new Resampler(Resampler::FastestTolerable, |
114 m_channelCount, | 114 m_channelCount, |
115 m_cacheWriteBufferSize); | 115 m_cacheWriteBufferSize); |
116 float ratio = float(m_sampleRate) / float(m_fileRate); | 116 double ratio = double(m_sampleRate) / double(m_fileRate); |
117 m_resampleBuffer = new float | 117 m_resampleBuffer = new float |
118 [lrintf(ceilf(m_cacheWriteBufferSize * m_channelCount * ratio + 1))]; | 118 [lrint(ceil(double(m_cacheWriteBufferSize) * m_channelCount * ratio + 1))]; |
119 } | 119 } |
120 | 120 |
121 m_cacheWriteBuffer = new float[m_cacheWriteBufferSize * m_channelCount]; | 121 m_cacheWriteBuffer = new float[m_cacheWriteBufferSize * m_channelCount]; |
122 m_cacheWriteBufferIndex = 0; | 122 m_cacheWriteBufferIndex = 0; |
123 | 123 |
174 | 174 |
175 m_initialised = true; | 175 m_initialised = true; |
176 } | 176 } |
177 | 177 |
178 void | 178 void |
179 CodedAudioFileReader::addSamplesToDecodeCache(float **samples, int nframes) | 179 CodedAudioFileReader::addSamplesToDecodeCache(float **samples, sv_frame_t nframes) |
180 { | 180 { |
181 QMutexLocker locker(&m_cacheMutex); | 181 QMutexLocker locker(&m_cacheMutex); |
182 | 182 |
183 if (!m_initialised) return; | 183 if (!m_initialised) return; |
184 | 184 |
185 for (int i = 0; i < nframes; ++i) { | 185 for (sv_frame_t i = 0; i < nframes; ++i) { |
186 | 186 |
187 for (int c = 0; c < m_channelCount; ++c) { | 187 for (int c = 0; c < m_channelCount; ++c) { |
188 | 188 |
189 float sample = samples[c][i]; | 189 float sample = samples[c][i]; |
190 | 190 |
204 } | 204 } |
205 } | 205 } |
206 } | 206 } |
207 | 207 |
208 void | 208 void |
209 CodedAudioFileReader::addSamplesToDecodeCache(float *samples, int nframes) | 209 CodedAudioFileReader::addSamplesToDecodeCache(float *samples, sv_frame_t nframes) |
210 { | 210 { |
211 QMutexLocker locker(&m_cacheMutex); | 211 QMutexLocker locker(&m_cacheMutex); |
212 | 212 |
213 if (!m_initialised) return; | 213 if (!m_initialised) return; |
214 | 214 |
215 for (int i = 0; i < nframes; ++i) { | 215 for (sv_frame_t i = 0; i < nframes; ++i) { |
216 | 216 |
217 for (int c = 0; c < m_channelCount; ++c) { | 217 for (int c = 0; c < m_channelCount; ++c) { |
218 | 218 |
219 float sample = samples[i * m_channelCount + c]; | 219 float sample = samples[i * m_channelCount + c]; |
220 | 220 |
240 { | 240 { |
241 QMutexLocker locker(&m_cacheMutex); | 241 QMutexLocker locker(&m_cacheMutex); |
242 | 242 |
243 if (!m_initialised) return; | 243 if (!m_initialised) return; |
244 | 244 |
245 for (int i = 0; i < (int)samples.size(); ++i) { | 245 for (float sample: samples) { |
246 | |
247 float sample = samples[i]; | |
248 | 246 |
249 m_cacheWriteBuffer[m_cacheWriteBufferIndex++] = sample; | 247 m_cacheWriteBuffer[m_cacheWriteBufferIndex++] = sample; |
250 | 248 |
251 if (m_cacheWriteBufferIndex == | 249 if (m_cacheWriteBufferIndex == |
252 m_cacheWriteBufferSize * m_channelCount) { | 250 m_cacheWriteBufferSize * m_channelCount) { |
293 if (m_cacheFileReader) m_cacheFileReader->updateFrameCount(); | 291 if (m_cacheFileReader) m_cacheFileReader->updateFrameCount(); |
294 } | 292 } |
295 } | 293 } |
296 | 294 |
297 void | 295 void |
298 CodedAudioFileReader::pushBuffer(float *buffer, int sz, bool final) | 296 CodedAudioFileReader::pushBuffer(float *buffer, sv_frame_t sz, bool final) |
299 { | 297 { |
300 m_fileFrameCount += sz; | 298 m_fileFrameCount += sz; |
301 | 299 |
302 float ratio = 1.f; | 300 float ratio = 1.f; |
303 if (m_resampler && m_fileRate != 0) { | 301 if (m_resampler && m_fileRate != 0) { |
310 pushBufferNonResampling(buffer, sz); | 308 pushBufferNonResampling(buffer, sz); |
311 } | 309 } |
312 } | 310 } |
313 | 311 |
314 void | 312 void |
315 CodedAudioFileReader::pushBufferNonResampling(float *buffer, int sz) | 313 CodedAudioFileReader::pushBufferNonResampling(float *buffer, sv_frame_t sz) |
316 { | 314 { |
317 float clip = 1.0; | 315 float clip = 1.0; |
318 int count = sz * m_channelCount; | 316 sv_frame_t count = sz * m_channelCount; |
319 | 317 |
320 if (m_normalised) { | 318 if (m_normalised) { |
321 for (int i = 0; i < count; ++i) { | 319 for (sv_frame_t i = 0; i < count; ++i) { |
322 float v = fabsf(buffer[i]); | 320 float v = fabsf(buffer[i]); |
323 if (v > m_max) { | 321 if (v > m_max) { |
324 m_max = v; | 322 m_max = v; |
325 m_gain = 1.f / m_max; | 323 m_gain = 1.f / m_max; |
326 } | 324 } |
327 } | 325 } |
328 } else { | 326 } else { |
329 for (int i = 0; i < count; ++i) { | 327 for (sv_frame_t i = 0; i < count; ++i) { |
330 if (buffer[i] > clip) buffer[i] = clip; | 328 if (buffer[i] > clip) buffer[i] = clip; |
331 } | 329 } |
332 for (int i = 0; i < count; ++i) { | 330 for (sv_frame_t i = 0; i < count; ++i) { |
333 if (buffer[i] < -clip) buffer[i] = -clip; | 331 if (buffer[i] < -clip) buffer[i] = -clip; |
334 } | 332 } |
335 } | 333 } |
336 | 334 |
337 m_frameCount += sz; | 335 m_frameCount += sz; |
338 | 336 |
339 switch (m_cacheMode) { | 337 switch (m_cacheMode) { |
340 | 338 |
341 case CacheInTemporaryFile: | 339 case CacheInTemporaryFile: |
342 if (sf_writef_float(m_cacheFileWritePtr, buffer, sz) < (int)sz) { | 340 if (sf_writef_float(m_cacheFileWritePtr, buffer, sz) < sz) { |
343 sf_close(m_cacheFileWritePtr); | 341 sf_close(m_cacheFileWritePtr); |
344 m_cacheFileWritePtr = 0; | 342 m_cacheFileWritePtr = 0; |
345 throw InsufficientDiscSpace(TempDirectory::getInstance()->getPath()); | 343 throw InsufficientDiscSpace(TempDirectory::getInstance()->getPath()); |
346 } | 344 } |
347 break; | 345 break; |
348 | 346 |
349 case CacheInMemory: | 347 case CacheInMemory: |
350 m_dataLock.lockForWrite(); | 348 m_dataLock.lockForWrite(); |
351 for (int s = 0; s < count; ++s) { | 349 for (sv_frame_t s = 0; s < count; ++s) { |
352 m_data.push_back(buffer[s]); | 350 m_data.push_back(buffer[s]); |
353 } | 351 } |
354 MUNLOCK_SAMPLEBLOCK(m_data); | 352 MUNLOCK_SAMPLEBLOCK(m_data); |
355 m_dataLock.unlock(); | 353 m_dataLock.unlock(); |
356 break; | 354 break; |
357 } | 355 } |
358 } | 356 } |
359 | 357 |
360 void | 358 void |
361 CodedAudioFileReader::pushBufferResampling(float *buffer, int sz, | 359 CodedAudioFileReader::pushBufferResampling(float *buffer, sv_frame_t sz, |
362 float ratio, bool final) | 360 double ratio, bool final) |
363 { | 361 { |
364 SVDEBUG << "pushBufferResampling: ratio = " << ratio << ", sz = " << sz << ", final = " << final << endl; | 362 SVDEBUG << "pushBufferResampling: ratio = " << ratio << ", sz = " << sz << ", final = " << final << endl; |
365 | 363 |
366 if (sz > 0) { | 364 if (sz > 0) { |
367 | 365 |
368 int out = m_resampler->resampleInterleaved | 366 sv_frame_t out = m_resampler->resampleInterleaved |
369 (buffer, | 367 (buffer, |
370 m_resampleBuffer, | 368 m_resampleBuffer, |
371 sz, | 369 sz, |
372 ratio, | 370 ratio, |
373 false); | 371 false); |
375 pushBufferNonResampling(m_resampleBuffer, out); | 373 pushBufferNonResampling(m_resampleBuffer, out); |
376 } | 374 } |
377 | 375 |
378 if (final) { | 376 if (final) { |
379 | 377 |
380 int padFrames = 1; | 378 sv_frame_t padFrames = 1; |
381 if (m_frameCount / ratio < m_fileFrameCount) { | 379 if (double(m_frameCount) / ratio < double(m_fileFrameCount)) { |
382 padFrames = m_fileFrameCount - (m_frameCount / ratio) + 1; | 380 padFrames = m_fileFrameCount - sv_frame_t(double(m_frameCount) / ratio) + 1; |
383 } | 381 } |
384 | 382 |
385 int padSamples = padFrames * m_channelCount; | 383 sv_frame_t padSamples = padFrames * m_channelCount; |
386 | 384 |
387 SVDEBUG << "frameCount = " << m_frameCount << ", equivFileFrames = " << m_frameCount / ratio << ", m_fileFrameCount = " << m_fileFrameCount << ", padFrames= " << padFrames << ", padSamples = " << padSamples << endl; | 385 SVDEBUG << "frameCount = " << m_frameCount << ", equivFileFrames = " << double(m_frameCount) / ratio << ", m_fileFrameCount = " << m_fileFrameCount << ", padFrames= " << padFrames << ", padSamples = " << padSamples << endl; |
388 | 386 |
389 float *padding = new float[padSamples]; | 387 float *padding = new float[padSamples]; |
390 for (int i = 0; i < padSamples; ++i) padding[i] = 0.f; | 388 for (sv_frame_t i = 0; i < padSamples; ++i) padding[i] = 0.f; |
391 | 389 |
392 int out = m_resampler->resampleInterleaved | 390 sv_frame_t out = m_resampler->resampleInterleaved |
393 (padding, | 391 (padding, |
394 m_resampleBuffer, | 392 m_resampleBuffer, |
395 padFrames, | 393 padFrames, |
396 ratio, | 394 ratio, |
397 true); | 395 true); |
398 | 396 |
399 if (int(m_frameCount + out) > int(m_fileFrameCount * ratio)) { | 397 if (m_frameCount + out > sv_frame_t(double(m_fileFrameCount) * ratio)) { |
400 out = int(m_fileFrameCount * ratio) - int(m_frameCount); | 398 out = sv_frame_t(double(m_fileFrameCount) * ratio) - m_frameCount; |
401 } | 399 } |
402 | 400 |
403 pushBufferNonResampling(m_resampleBuffer, out); | 401 pushBufferNonResampling(m_resampleBuffer, out); |
404 delete[] padding; | 402 delete[] padding; |
405 } | 403 } |
406 } | 404 } |
407 | 405 |
408 void | 406 void |
409 CodedAudioFileReader::getInterleavedFrames(int start, int count, | 407 CodedAudioFileReader::getInterleavedFrames(sv_frame_t start, sv_frame_t count, |
410 SampleBlock &frames) const | 408 SampleBlock &frames) const |
411 { | 409 { |
412 // Lock is only required in CacheInMemory mode (the cache file | 410 // Lock is only required in CacheInMemory mode (the cache file |
413 // reader is expected to be thread safe and manage its own | 411 // reader is expected to be thread safe and manage its own |
414 // locking) | 412 // locking) |
431 frames.clear(); | 429 frames.clear(); |
432 if (!isOK()) return; | 430 if (!isOK()) return; |
433 if (count == 0) return; | 431 if (count == 0) return; |
434 frames.reserve(count * m_channelCount); | 432 frames.reserve(count * m_channelCount); |
435 | 433 |
436 int idx = start * m_channelCount; | 434 sv_frame_t idx = start * m_channelCount; |
437 int i = 0; | 435 sv_frame_t i = 0; |
438 | 436 |
439 m_dataLock.lockForRead(); | 437 m_dataLock.lockForRead(); |
440 while (i < count * m_channelCount && idx < (int)m_data.size()) { | 438 while (i < count * m_channelCount && idx < (sv_frame_t)m_data.size()) { |
441 frames.push_back(m_data[idx]); | 439 frames.push_back(m_data[idx]); |
442 ++idx; | 440 ++idx; |
443 } | 441 } |
444 m_dataLock.unlock(); | 442 m_dataLock.unlock(); |
445 } | 443 } |
446 } | 444 } |
447 | 445 |
448 if (m_normalised) { | 446 if (m_normalised) { |
449 for (int i = 0; i < (int)(count * m_channelCount); ++i) { | 447 for (sv_frame_t i = 0; i < (sv_frame_t)(count * m_channelCount); ++i) { |
450 frames[i] *= m_gain; | 448 frames[i] *= m_gain; |
451 } | 449 } |
452 } | 450 } |
453 } | 451 } |
454 | 452 |