comparison audio/AudioCallbackPlaySource.cpp @ 546:4de547a5905c 3.0-integration

Update for bqaudioio changes
author Chris Cannam
date Tue, 06 Dec 2016 15:59:06 +0000
parents 699db455a3e1
children c732251237b1
comparison
equal deleted inserted replaced
543:699db455a3e1 546:4de547a5905c
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 {
1368 1321
1369 #ifdef DEBUG_AUDIO_PLAY_SOURCE 1322 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1370 cout << "buffered to " << f << " already" << endl; 1323 cout << "buffered to " << f << " already" << endl;
1371 #endif 1324 #endif
1372 1325
1373 bool resample = (getSourceSampleRate() != getTargetSampleRate());
1374
1375 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1376 cout << (resample ? "" : "not ") << "resampling (source " << getSourceSampleRate() << ", target " << getTargetSampleRate() << ")" << endl;
1377 #endif
1378
1379 int channels = getTargetChannelCount(); 1326 int channels = getTargetChannelCount();
1380 1327
1381 sv_frame_t orig = space; 1328 sv_frame_t orig = space;
1382 sv_frame_t got = 0;
1383 1329
1384 static float **bufferPtrs = 0; 1330 static float **bufferPtrs = 0;
1385 static int bufferPtrCount = 0; 1331 static int bufferPtrCount = 0;
1386 1332
1387 if (bufferPtrCount < channels) { 1333 if (bufferPtrCount < channels) {
1390 bufferPtrCount = channels; 1336 bufferPtrCount = channels;
1391 } 1337 }
1392 1338
1393 sv_frame_t generatorBlockSize = m_audioGenerator->getBlockSize(); 1339 sv_frame_t generatorBlockSize = m_audioGenerator->getBlockSize();
1394 1340
1395 if (resample && !m_resampler) { 1341 // space must be a multiple of generatorBlockSize
1396 throw std::logic_error("Sample rates differ, but no resampler available!"); 1342 sv_frame_t reqSpace = space;
1397 } 1343 space = (reqSpace / generatorBlockSize) * generatorBlockSize;
1398 1344 if (space == 0) {
1399 if (resample && m_resampler) { 1345 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1400 1346 cout << "requested fill of " << reqSpace
1401 double ratio = 1347 << " is less than generator block size of "
1402 double(getTargetSampleRate()) / double(getSourceSampleRate()); 1348 << generatorBlockSize << ", leaving it" << endl;
1403 orig = sv_frame_t(double(orig) / ratio + 0.1); 1349 #endif
1404 1350 return false;
1405 // orig must be a multiple of generatorBlockSize 1351 }
1406 orig = (orig / generatorBlockSize) * generatorBlockSize; 1352
1407 if (orig == 0) return false; 1353 if (tmpSize < channels * space) {
1408 1354 delete[] tmp;
1409 sv_frame_t work = std::max(orig, space); 1355 tmp = new float[channels * space];
1410 1356 tmpSize = channels * space;
1411 // We only allocate one buffer, but we use it in two halves. 1357 }
1412 // We place the non-interleaved values in the second half of 1358
1413 // the buffer (orig samples for channel 0, orig samples for 1359 for (int c = 0; c < channels; ++c) {
1414 // channel 1 etc), and then interleave them into the first 1360
1415 // half of the buffer. Then we resample back into the second 1361 bufferPtrs[c] = tmp + c * space;
1416 // half (interleaved) and de-interleave the results back to
1417 // the start of the buffer for insertion into the ringbuffers.
1418 // What a faff -- especially as we've already de-interleaved
1419 // the audio data from the source file elsewhere before we
1420 // even reach this point.
1421
1422 if (tmpSize < channels * work * 2) {
1423 delete[] tmp;
1424 tmp = new float[channels * work * 2];
1425 tmpSize = channels * work * 2;
1426 }
1427
1428 float *nonintlv = tmp + channels * work;
1429 float *intlv = tmp;
1430 float *srcout = tmp + channels * work;
1431
1432 for (int c = 0; c < channels; ++c) {
1433 for (int i = 0; i < orig; ++i) {
1434 nonintlv[channels * i + c] = 0.0f;
1435 }
1436 }
1437
1438 for (int c = 0; c < channels; ++c) {
1439 bufferPtrs[c] = nonintlv + c * orig;
1440 }
1441
1442 got = mixModels(f, orig, bufferPtrs); // also modifies f
1443
1444 // and interleave into first half
1445 for (int c = 0; c < channels; ++c) {
1446 for (int i = 0; i < got; ++i) {
1447 float sample = nonintlv[c * got + i];
1448 intlv[channels * i + c] = sample;
1449 }
1450 }
1451
1452 SRC_DATA data;
1453 data.data_in = intlv;
1454 data.data_out = srcout;
1455 data.input_frames = long(got);
1456 data.output_frames = long(work);
1457 data.src_ratio = ratio;
1458 data.end_of_input = 0;
1459
1460 int err = src_process(m_converter, &data);
1461
1462 sv_frame_t toCopy = sv_frame_t(double(got) * ratio + 0.1);
1463
1464 if (err) {
1465 cerr
1466 << "AudioCallbackPlaySourceFillThread: ERROR in samplerate conversion: "
1467 << src_strerror(err) << endl;
1468 //!!! Then what?
1469 } else {
1470 got = data.input_frames_used;
1471 toCopy = data.output_frames_gen;
1472 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1473 cout << "Resampled " << got << " frames to " << toCopy << " frames" << endl;
1474 #endif
1475 }
1476
1477 for (int c = 0; c < channels; ++c) {
1478 for (int i = 0; i < toCopy; ++i) {
1479 tmp[i] = srcout[channels * i + c];
1480 }
1481 RingBuffer<float> *wb = getWriteRingBuffer(c);
1482 if (wb) wb->write(tmp, int(toCopy));
1483 }
1484
1485 m_writeBufferFill = f;
1486 if (readWriteEqual) m_readBufferFill = f;
1487
1488 } else {
1489
1490 // space must be a multiple of generatorBlockSize
1491 sv_frame_t reqSpace = space;
1492 space = (reqSpace / generatorBlockSize) * generatorBlockSize;
1493 if (space == 0) {
1494 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1495 cout << "requested fill of " << reqSpace
1496 << " is less than generator block size of "
1497 << generatorBlockSize << ", leaving it" << endl;
1498 #endif
1499 return false;
1500 }
1501
1502 if (tmpSize < channels * space) {
1503 delete[] tmp;
1504 tmp = new float[channels * space];
1505 tmpSize = channels * space;
1506 }
1507
1508 for (int c = 0; c < channels; ++c) {
1509
1510 bufferPtrs[c] = tmp + c * space;
1511 1362
1512 for (int i = 0; i < space; ++i) { 1363 for (int i = 0; i < space; ++i) {
1513 tmp[c * space + i] = 0.0f; 1364 tmp[c * space + i] = 0.0f;
1514 } 1365 }
1515 } 1366 }
1516 1367
1517 sv_frame_t got = mixModels(f, space, bufferPtrs); // also modifies f 1368 sv_frame_t got = mixModels(f, space, bufferPtrs); // also modifies f
1518 1369
1519 for (int c = 0; c < channels; ++c) { 1370 for (int c = 0; c < channels; ++c) {
1520 1371
1521 RingBuffer<float> *wb = getWriteRingBuffer(c); 1372 RingBuffer<float> *wb = getWriteRingBuffer(c);
1522 if (wb) { 1373 if (wb) {
1523 int actual = wb->write(bufferPtrs[c], int(got)); 1374 int actual = wb->write(bufferPtrs[c], int(got));
1524 #ifdef DEBUG_AUDIO_PLAY_SOURCE 1375 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1525 cout << "Wrote " << actual << " samples for ch " << c << ", now " 1376 cout << "Wrote " << actual << " samples for ch " << c << ", now "
1526 << wb->getReadSpace() << " to read" 1377 << wb->getReadSpace() << " to read"
1527 << endl; 1378 << endl;
1528 #endif 1379 #endif
1529 if (actual < got) { 1380 if (actual < got) {
1530 cerr << "WARNING: Buffer overrun in channel " << c 1381 cerr << "WARNING: Buffer overrun in channel " << c
1531 << ": wrote " << actual << " of " << got 1382 << ": wrote " << actual << " of " << got
1532 << " samples" << endl; 1383 << " samples" << endl;
1533 }
1534 } 1384 }
1535 } 1385 }
1536 1386 }
1537 m_writeBufferFill = f; 1387
1538 if (readWriteEqual) m_readBufferFill = f; 1388 m_writeBufferFill = f;
1539 1389 if (readWriteEqual) m_readBufferFill = f;
1540 #ifdef DEBUG_AUDIO_PLAY_SOURCE 1390
1541 cout << "Read buffer fill is now " << m_readBufferFill << endl; 1391 #ifdef DEBUG_AUDIO_PLAY_SOURCE
1542 #endif 1392 cout << "Read buffer fill is now " << m_readBufferFill << endl;
1543 1393 #endif
1544 //!!! 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 1394
1545 } 1395 //!!! 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
1546 1396
1547 return true; 1397 return true;
1548 } 1398 }
1549 1399
1550 sv_frame_t 1400 sv_frame_t