comparison audio/AudioCallbackPlaySource.cpp @ 550:c732251237b1 bqresample

Merge from branch 3.0-integration
author Chris Cannam
date Wed, 07 Dec 2016 12:04:41 +0000
parents c4391f6c7484 4de547a5905c
children b9d8c7a690d6
comparison
equal deleted inserted replaced
549:ec189ad4d38f 550:c732251237b1
75 m_stretchRatio(1.0), 75 m_stretchRatio(1.0),
76 m_stretchMono(false), 76 m_stretchMono(false),
77 m_stretcherInputCount(0), 77 m_stretcherInputCount(0),
78 m_stretcherInputs(0), 78 m_stretcherInputs(0),
79 m_stretcherInputSizes(0), 79 m_stretcherInputSizes(0),
80 m_fillThread(0), 80 m_fillThread(0)
81 m_resampler(0)
82 { 81 {
83 m_viewManager->setAudioPlaySource(this); 82 m_viewManager->setAudioPlaySource(this);
84 83
85 connect(m_viewManager, SIGNAL(selectionChanged()), 84 connect(m_viewManager, SIGNAL(selectionChanged()),
86 this, SLOT(selectionChanged())); 85 this, SLOT(selectionChanged()));
228 } else { 227 } else {
229 if (willPlay) clearRingBuffers(true); 228 if (willPlay) clearRingBuffers(true);
230 } 229 }
231 230
232 if (buffersChanged || srChanged) { 231 if (buffersChanged || srChanged) {
233 if (m_resampler) { 232
234 #ifdef DEBUG_AUDIO_PLAY_SOURCE 233 // There are more channels than there were before, or the
235 cerr << "AudioCallbackPlaySource::addModel: Buffers or sample rate changed, deleting existing resampler" << endl; 234 // source sample rate has changed
236 #endif 235
237 delete m_resampler; 236 //!!!
238 m_resampler = 0; 237
239 }
240 } 238 }
241 239
242 rebuildRangeLists(); 240 rebuildRangeLists();
243 241
244 m_mutex.unlock(); 242 m_mutex.unlock();
245 243
246 initialiseResampler(); 244 //!!!
247 245
248 m_audioGenerator->setTargetChannelCount(getTargetChannelCount()); 246 m_audioGenerator->setTargetChannelCount(getTargetChannelCount());
249 247
250 if (!m_fillThread) { 248 if (!m_fillThread) {
251 m_fillThread = new FillThread(*this); 249 m_fillThread = new FillThread(*this);
299 this, SLOT(modelChangedWithin(sv_frame_t, sv_frame_t))); 297 this, SLOT(modelChangedWithin(sv_frame_t, sv_frame_t)));
300 298
301 m_models.erase(model); 299 m_models.erase(model);
302 300
303 if (m_models.empty()) { 301 if (m_models.empty()) {
304 if (m_resampler) {
305 #ifdef DEBUG_AUDIO_PLAY_SOURCE
306 cerr << "AudioCallbackPlaySource::removeModel: No models left, deleting resampler" << endl;
307 #endif
308 delete m_resampler;
309 m_resampler = 0;
310 }
311 m_sourceSampleRate = 0; 302 m_sourceSampleRate = 0;
312 } 303 }
313 304
314 sv_frame_t lastEnd = 0; 305 sv_frame_t lastEnd = 0;
315 for (std::set<Model *>::const_iterator i = m_models.begin(); 306 for (std::set<Model *>::const_iterator i = m_models.begin();
341 #ifdef DEBUG_AUDIO_PLAY_SOURCE 332 #ifdef DEBUG_AUDIO_PLAY_SOURCE
342 cout << "AudioCallbackPlaySource::clearModels()" << endl; 333 cout << "AudioCallbackPlaySource::clearModels()" << endl;
343 #endif 334 #endif
344 335
345 m_models.clear(); 336 m_models.clear();
346
347 if (m_resampler) {
348 #ifdef DEBUG_AUDIO_PLAY_SOURCE
349 cerr << "AudioCallbackPlaySource::clearModels: Deleting resampler" << endl;
350 #endif
351 delete m_resampler;
352 m_resampler = 0;
353 }
354 337
355 m_lastModelEndFrame = 0; 338 m_lastModelEndFrame = 0;
356 339
357 m_sourceSampleRate = 0; 340 m_sourceSampleRate = 0;
358 341
469 #ifdef DEBUG_AUDIO_PLAY_SOURCE 452 #ifdef DEBUG_AUDIO_PLAY_SOURCE
470 cerr << "reset ring buffer for channel " << c << endl; 453 cerr << "reset ring buffer for channel " << c << endl;
471 #endif 454 #endif
472 if (rb) rb->reset(); 455 if (rb) rb->reset();
473 } 456 }
474 }
475 if (m_resampler) {
476 m_resampler->reset();
477 } 457 }
478 458
479 m_mutex.unlock(); 459 m_mutex.unlock();
480 460
481 m_audioGenerator->reset(); 461 m_audioGenerator->reset();
945 AudioCallbackPlaySource::setSystemPlaybackSampleRate(int sr) 925 AudioCallbackPlaySource::setSystemPlaybackSampleRate(int sr)
946 { 926 {
947 bool first = (m_targetSampleRate == 0); 927 bool first = (m_targetSampleRate == 0);
948 928
949 m_targetSampleRate = sr; 929 m_targetSampleRate = sr;
950 initialiseResampler();
951 930
952 if (first && (m_stretchRatio != 1.f)) { 931 if (first && (m_stretchRatio != 1.f)) {
953 // couldn't create a stretcher before because we had no sample 932 // couldn't create a stretcher before because we had no sample
954 // rate: make one now 933 // rate: make one now
955 setTimeStretch(m_stretchRatio); 934 setTimeStretch(m_stretchRatio);
956 } 935 }
957 } 936 }
958 937
959 void 938 void
960 AudioCallbackPlaySource::initialiseResampler() 939 AudioCallbackPlaySource::setSystemPlaybackChannelCount(int c)
961 { 940 {
962 m_mutex.lock();
963
964 #ifdef DEBUG_AUDIO_PLAY_SOURCE
965 cerr << "AudioCallbackPlaySource::initialiseResampler(): from "
966 << getSourceSampleRate() << " to " << getTargetSampleRate() << endl;
967 #endif
968
969 if (m_resampler) {
970 delete m_resampler;
971 m_resampler = 0;
972 }
973
974 if (getSourceSampleRate() != getTargetSampleRate()) {
975
976 m_resampler = new breakfastquay::Resampler
977 (breakfastquay::Resampler::FastestTolerable,
978 getTargetChannelCount());
979
980 m_mutex.unlock();
981
982 emit sampleRateMismatch(getSourceSampleRate(),
983 getTargetSampleRate(),
984 true);
985 } else {
986 m_mutex.unlock();
987 }
988 } 941 }
989 942
990 void 943 void
991 AudioCallbackPlaySource::setAuditioningEffect(Auditionable *a) 944 AudioCallbackPlaySource::setAuditioningEffect(Auditionable *a)
992 { 945 {
1371 1324
1372 #ifdef DEBUG_AUDIO_PLAY_SOURCE 1325 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1373 cout << "buffered to " << f << " already" << endl; 1326 cout << "buffered to " << f << " already" << endl;
1374 #endif 1327 #endif
1375 1328
1376 bool resample = (getSourceSampleRate() != getTargetSampleRate());
1377
1378 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1379 cout << (resample ? "" : "not ") << "resampling (source " << getSourceSampleRate() << ", target " << getTargetSampleRate() << ")" << endl;
1380 #endif
1381
1382 int channels = getTargetChannelCount(); 1329 int channels = getTargetChannelCount();
1383 1330
1384 sv_frame_t orig = space; 1331 sv_frame_t orig = space;
1385 sv_frame_t got = 0;
1386 1332
1387 static float **bufferPtrs = 0; 1333 static float **bufferPtrs = 0;
1388 static int bufferPtrCount = 0; 1334 static int bufferPtrCount = 0;
1389 1335
1390 if (bufferPtrCount < channels) { 1336 if (bufferPtrCount < channels) {
1393 bufferPtrCount = channels; 1339 bufferPtrCount = channels;
1394 } 1340 }
1395 1341
1396 sv_frame_t generatorBlockSize = m_audioGenerator->getBlockSize(); 1342 sv_frame_t generatorBlockSize = m_audioGenerator->getBlockSize();
1397 1343
1398 if (resample && !m_resampler) { 1344 // space must be a multiple of generatorBlockSize
1399 throw std::logic_error("Sample rates differ, but no resampler available!"); 1345 sv_frame_t reqSpace = space;
1400 } 1346 space = (reqSpace / generatorBlockSize) * generatorBlockSize;
1401 1347 if (space == 0) {
1402 if (resample && m_resampler) { 1348 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1403 1349 cout << "requested fill of " << reqSpace
1404 double ratio = 1350 << " is less than generator block size of "
1405 double(getTargetSampleRate()) / double(getSourceSampleRate()); 1351 << generatorBlockSize << ", leaving it" << endl;
1406 orig = sv_frame_t(double(orig) / ratio + 0.1); 1352 #endif
1407 1353 return false;
1408 // orig must be a multiple of generatorBlockSize 1354 }
1409 orig = (orig / generatorBlockSize) * generatorBlockSize; 1355
1410 if (orig == 0) return false; 1356 if (tmpSize < channels * space) {
1411 1357 delete[] tmp;
1412 sv_frame_t work = std::max(orig, space); 1358 tmp = new float[channels * space];
1413 1359 tmpSize = channels * space;
1414 // We only allocate one buffer, but we use it in two halves. 1360 }
1415 // We place the non-interleaved values in the second half of 1361
1416 // the buffer (orig samples for channel 0, orig samples for 1362 for (int c = 0; c < channels; ++c) {
1417 // channel 1 etc), and then interleave them into the first 1363
1418 // half of the buffer. Then we resample back into the second 1364 bufferPtrs[c] = tmp + c * space;
1419 // half (interleaved) and de-interleave the results back to
1420 // the start of the buffer for insertion into the ringbuffers.
1421 // What a faff -- especially as we've already de-interleaved
1422 // the audio data from the source file elsewhere before we
1423 // even reach this point.
1424
1425 if (tmpSize < channels * work * 2) {
1426 delete[] tmp;
1427 tmp = new float[channels * work * 2];
1428 tmpSize = channels * work * 2;
1429 }
1430
1431 float *nonintlv = tmp + channels * work;
1432 float *intlv = tmp;
1433 float *srcout = tmp + channels * work;
1434
1435 for (int c = 0; c < channels; ++c) {
1436 for (int i = 0; i < orig; ++i) {
1437 nonintlv[channels * i + c] = 0.0f;
1438 }
1439 }
1440
1441 for (int c = 0; c < channels; ++c) {
1442 bufferPtrs[c] = nonintlv + c * orig;
1443 }
1444
1445 got = mixModels(f, orig, bufferPtrs); // also modifies f
1446
1447 // and interleave into first half
1448 for (int c = 0; c < channels; ++c) {
1449 for (int i = 0; i < got; ++i) {
1450 float sample = nonintlv[c * got + i];
1451 intlv[channels * i + c] = sample;
1452 }
1453 }
1454
1455 sv_frame_t toCopy = m_resampler->resampleInterleaved
1456 (intlv, srcout, got, ratio, false);
1457
1458 SRC_DATA data;
1459 data.data_in = intlv;
1460 data.data_out = srcout;
1461 data.input_frames = long(got);
1462 data.output_frames = long(work);
1463 data.src_ratio = ratio;
1464 data.end_of_input = 0;
1465
1466 int err = src_process(m_converter, &data);
1467
1468 sv_frame_t toCopy = sv_frame_t(double(got) * ratio + 0.1);
1469
1470 if (err) {
1471 cerr
1472 << "AudioCallbackPlaySourceFillThread: ERROR in samplerate conversion: "
1473 << src_strerror(err) << endl;
1474 //!!! Then what?
1475 } else {
1476 got = data.input_frames_used;
1477 toCopy = data.output_frames_gen;
1478 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1479 cout << "Resampled " << got << " frames to " << toCopy << " frames" << endl;
1480 #endif
1481 }
1482
1483 for (int c = 0; c < channels; ++c) {
1484 for (int i = 0; i < toCopy; ++i) {
1485 tmp[i] = srcout[channels * i + c];
1486 }
1487 RingBuffer<float> *wb = getWriteRingBuffer(c);
1488 if (wb) wb->write(tmp, int(toCopy));
1489 }
1490
1491 m_writeBufferFill = f;
1492 if (readWriteEqual) m_readBufferFill = f;
1493
1494 } else {
1495
1496 // space must be a multiple of generatorBlockSize
1497 sv_frame_t reqSpace = space;
1498 space = (reqSpace / generatorBlockSize) * generatorBlockSize;
1499 if (space == 0) {
1500 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1501 cout << "requested fill of " << reqSpace
1502 << " is less than generator block size of "
1503 << generatorBlockSize << ", leaving it" << endl;
1504 #endif
1505 return false;
1506 }
1507
1508 if (tmpSize < channels * space) {
1509 delete[] tmp;
1510 tmp = new float[channels * space];
1511 tmpSize = channels * space;
1512 }
1513
1514 for (int c = 0; c < channels; ++c) {
1515
1516 bufferPtrs[c] = tmp + c * space;
1517 1365
1518 for (int i = 0; i < space; ++i) { 1366 for (int i = 0; i < space; ++i) {
1519 tmp[c * space + i] = 0.0f; 1367 tmp[c * space + i] = 0.0f;
1520 } 1368 }
1521 } 1369 }
1522 1370
1523 sv_frame_t got = mixModels(f, space, bufferPtrs); // also modifies f 1371 sv_frame_t got = mixModels(f, space, bufferPtrs); // also modifies f
1524 1372
1525 for (int c = 0; c < channels; ++c) { 1373 for (int c = 0; c < channels; ++c) {
1526 1374
1527 RingBuffer<float> *wb = getWriteRingBuffer(c); 1375 RingBuffer<float> *wb = getWriteRingBuffer(c);
1528 if (wb) { 1376 if (wb) {
1529 int actual = wb->write(bufferPtrs[c], int(got)); 1377 int actual = wb->write(bufferPtrs[c], int(got));
1530 #ifdef DEBUG_AUDIO_PLAY_SOURCE 1378 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1531 cout << "Wrote " << actual << " samples for ch " << c << ", now " 1379 cout << "Wrote " << actual << " samples for ch " << c << ", now "
1532 << wb->getReadSpace() << " to read" 1380 << wb->getReadSpace() << " to read"
1533 << endl; 1381 << endl;
1534 #endif 1382 #endif
1535 if (actual < got) { 1383 if (actual < got) {
1536 cerr << "WARNING: Buffer overrun in channel " << c 1384 cerr << "WARNING: Buffer overrun in channel " << c
1537 << ": wrote " << actual << " of " << got 1385 << ": wrote " << actual << " of " << got
1538 << " samples" << endl; 1386 << " samples" << endl;
1539 }
1540 } 1387 }
1541 } 1388 }
1542 1389 }
1543 m_writeBufferFill = f; 1390
1544 if (readWriteEqual) m_readBufferFill = f; 1391 m_writeBufferFill = f;
1545 1392 if (readWriteEqual) m_readBufferFill = f;
1546 #ifdef DEBUG_AUDIO_PLAY_SOURCE 1393
1547 cout << "Read buffer fill is now " << m_readBufferFill << endl; 1394 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1548 #endif 1395 cout << "Read buffer fill is now " << m_readBufferFill << endl;
1549 1396 #endif
1550 //!!! how do we know when ended? need to mark up a fully-buffered flag and check this if we find the buffers empty in getSourceSamples 1397
1551 } 1398 //!!! how do we know when ended? need to mark up a fully-buffered flag and check this if we find the buffers empty in getSourceSamples
1552 1399
1553 return true; 1400 return true;
1554 } 1401 }
1555 1402
1556 sv_frame_t 1403 sv_frame_t