Mercurial > hg > svapp
comparison audioio/AudioCallbackPlaySource.cpp @ 434:dee4aceb131c cxx11
Fixes to go with latest svcore
author | Chris Cannam |
---|---|
date | Wed, 04 Mar 2015 13:53:13 +0000 |
parents | b65ee5c4f8bc |
children | 618d5816b04d |
comparison
equal
deleted
inserted
replaced
433:720f732e8082 | 434:dee4aceb131c |
---|---|
395 m_mutex.unlock(); | 395 m_mutex.unlock(); |
396 } | 396 } |
397 } | 397 } |
398 | 398 |
399 void | 399 void |
400 AudioCallbackPlaySource::play(int startFrame) | 400 AudioCallbackPlaySource::play(sv_frame_t startFrame) |
401 { | 401 { |
402 if (!m_sourceSampleRate) { | 402 if (!m_sourceSampleRate) { |
403 cerr << "AudioCallbackPlaySource::play: No source sample rate available, not playing" << endl; | 403 cerr << "AudioCallbackPlaySource::play: No source sample rate available, not playing" << endl; |
404 return; | 404 return; |
405 } | 405 } |
595 // cout << "AudioCallbackPlaySource::getTargetBlockSize() -> " << m_blockSize << endl; | 595 // cout << "AudioCallbackPlaySource::getTargetBlockSize() -> " << m_blockSize << endl; |
596 return m_blockSize; | 596 return m_blockSize; |
597 } | 597 } |
598 | 598 |
599 void | 599 void |
600 AudioCallbackPlaySource::setTargetPlayLatency(int latency) | 600 AudioCallbackPlaySource::setTargetPlayLatency(sv_frame_t latency) |
601 { | 601 { |
602 m_playLatency = latency; | 602 m_playLatency = latency; |
603 } | 603 } |
604 | 604 |
605 int | 605 sv_frame_t |
606 AudioCallbackPlaySource::getTargetPlayLatency() const | 606 AudioCallbackPlaySource::getTargetPlayLatency() const |
607 { | 607 { |
608 return m_playLatency; | 608 return m_playLatency; |
609 } | 609 } |
610 | 610 |
611 int | 611 sv_frame_t |
612 AudioCallbackPlaySource::getCurrentPlayingFrame() | 612 AudioCallbackPlaySource::getCurrentPlayingFrame() |
613 { | 613 { |
614 // This method attempts to estimate which audio sample frame is | 614 // This method attempts to estimate which audio sample frame is |
615 // "currently coming through the speakers". | 615 // "currently coming through the speakers". |
616 | 616 |
623 } | 623 } |
624 | 624 |
625 return getCurrentFrame(latency_t); | 625 return getCurrentFrame(latency_t); |
626 } | 626 } |
627 | 627 |
628 int | 628 sv_frame_t |
629 AudioCallbackPlaySource::getCurrentBufferedFrame() | 629 AudioCallbackPlaySource::getCurrentBufferedFrame() |
630 { | 630 { |
631 return getCurrentFrame(RealTime::zeroTime); | 631 return getCurrentFrame(RealTime::zeroTime); |
632 } | 632 } |
633 | 633 |
634 int | 634 sv_frame_t |
635 AudioCallbackPlaySource::getCurrentFrame(RealTime latency_t) | 635 AudioCallbackPlaySource::getCurrentFrame(RealTime latency_t) |
636 { | 636 { |
637 // We resample when filling the ring buffer, and time-stretch when | 637 // We resample when filling the ring buffer, and time-stretch when |
638 // draining it. The buffer contains data at the "target rate" and | 638 // draining it. The buffer contains data at the "target rate" and |
639 // the latency provided by the target is also at the target rate. | 639 // the latency provided by the target is also at the target rate. |
640 // Because of the multiple rates involved, we do the actual | 640 // Because of the multiple rates involved, we do the actual |
641 // calculation using RealTime instead. | 641 // calculation using RealTime instead. |
642 | 642 |
643 int sourceRate = getSourceSampleRate(); | 643 sv_samplerate_t sourceRate = getSourceSampleRate(); |
644 int targetRate = getTargetSampleRate(); | 644 sv_samplerate_t targetRate = getTargetSampleRate(); |
645 | 645 |
646 if (sourceRate == 0 || targetRate == 0) return 0; | 646 if (sourceRate == 0 || targetRate == 0) return 0; |
647 | 647 |
648 int inbuffer = 0; // at target rate | 648 int inbuffer = 0; // at target rate |
649 | 649 |
737 // this code is only used in case of error in rebuildRangeLists | 737 // this code is only used in case of error in rebuildRangeLists |
738 RealTime playing_t = bufferedto_t | 738 RealTime playing_t = bufferedto_t |
739 - latency_t - stretchlat_t - lastretrieved_t - inbuffer_t | 739 - latency_t - stretchlat_t - lastretrieved_t - inbuffer_t |
740 + sincerequest_t; | 740 + sincerequest_t; |
741 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime; | 741 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime; |
742 int frame = RealTime::realTime2Frame(playing_t, sourceRate); | 742 sv_frame_t frame = RealTime::realTime2Frame(playing_t, sourceRate); |
743 return m_viewManager->alignPlaybackFrameToReference(frame); | 743 return m_viewManager->alignPlaybackFrameToReference(frame); |
744 } | 744 } |
745 | 745 |
746 int inRange = 0; | 746 int inRange = 0; |
747 int index = 0; | 747 int index = 0; |
831 } | 831 } |
832 } | 832 } |
833 | 833 |
834 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime; | 834 if (playing_t < RealTime::zeroTime) playing_t = RealTime::zeroTime; |
835 | 835 |
836 int frame = RealTime::realTime2Frame(playing_t, sourceRate); | 836 sv_frame_t frame = RealTime::realTime2Frame(playing_t, sourceRate); |
837 | 837 |
838 if (m_lastCurrentFrame > 0 && !looping) { | 838 if (m_lastCurrentFrame > 0 && !looping) { |
839 if (frame < m_lastCurrentFrame) { | 839 if (frame < m_lastCurrentFrame) { |
840 frame = m_lastCurrentFrame; | 840 frame = m_lastCurrentFrame; |
841 } | 841 } |
914 right = m_outputRight; | 914 right = m_outputRight; |
915 return true; | 915 return true; |
916 } | 916 } |
917 | 917 |
918 void | 918 void |
919 AudioCallbackPlaySource::setTargetSampleRate(int sr) | 919 AudioCallbackPlaySource::setTargetSampleRate(sv_samplerate_t sr) |
920 { | 920 { |
921 bool first = (m_targetSampleRate == 0); | 921 bool first = (m_targetSampleRate == 0); |
922 | 922 |
923 m_targetSampleRate = sr; | 923 m_targetSampleRate = sr; |
924 initialiseConverter(); | 924 initialiseConverter(); |
1031 { | 1031 { |
1032 m_audioGenerator->clearSoloModelSet(); | 1032 m_audioGenerator->clearSoloModelSet(); |
1033 clearRingBuffers(); | 1033 clearRingBuffers(); |
1034 } | 1034 } |
1035 | 1035 |
1036 int | 1036 sv_samplerate_t |
1037 AudioCallbackPlaySource::getTargetSampleRate() const | 1037 AudioCallbackPlaySource::getTargetSampleRate() const |
1038 { | 1038 { |
1039 if (m_targetSampleRate) return m_targetSampleRate; | 1039 if (m_targetSampleRate) return m_targetSampleRate; |
1040 else return getSourceSampleRate(); | 1040 else return getSourceSampleRate(); |
1041 } | 1041 } |
1051 { | 1051 { |
1052 if (m_sourceChannelCount < 2) return 2; | 1052 if (m_sourceChannelCount < 2) return 2; |
1053 return m_sourceChannelCount; | 1053 return m_sourceChannelCount; |
1054 } | 1054 } |
1055 | 1055 |
1056 int | 1056 sv_samplerate_t |
1057 AudioCallbackPlaySource::getSourceSampleRate() const | 1057 AudioCallbackPlaySource::getSourceSampleRate() const |
1058 { | 1058 { |
1059 return m_sourceSampleRate; | 1059 return m_sourceSampleRate; |
1060 } | 1060 } |
1061 | 1061 |
1091 } | 1091 } |
1092 | 1092 |
1093 emit activity(tr("Change time-stretch factor to %1").arg(factor)); | 1093 emit activity(tr("Change time-stretch factor to %1").arg(factor)); |
1094 } | 1094 } |
1095 | 1095 |
1096 int | 1096 sv_frame_t |
1097 AudioCallbackPlaySource::getSourceSamples(int ucount, float **buffer) | 1097 AudioCallbackPlaySource::getSourceSamples(sv_frame_t count, float **buffer) |
1098 { | 1098 { |
1099 int count = ucount; | |
1100 | |
1101 if (!m_playing) { | 1099 if (!m_playing) { |
1102 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING | 1100 #ifdef DEBUG_AUDIO_PLAY_SOURCE_PLAYING |
1103 SVDEBUG << "AudioCallbackPlaySource::getSourceSamples: Not playing" << endl; | 1101 SVDEBUG << "AudioCallbackPlaySource::getSourceSamples: Not playing" << endl; |
1104 #endif | 1102 #endif |
1105 for (int ch = 0; ch < getTargetChannelCount(); ++ch) { | 1103 for (int ch = 0; ch < getTargetChannelCount(); ++ch) { |
1307 | 1305 |
1308 return count; | 1306 return count; |
1309 } | 1307 } |
1310 | 1308 |
1311 void | 1309 void |
1312 AudioCallbackPlaySource::applyAuditioningEffect(int count, float **buffers) | 1310 AudioCallbackPlaySource::applyAuditioningEffect(sv_frame_t count, float **buffers) |
1313 { | 1311 { |
1314 if (m_auditioningPluginBypassed) return; | 1312 if (m_auditioningPluginBypassed) return; |
1315 RealTimePluginInstance *plugin = m_auditioningPlugin; | 1313 RealTimePluginInstance *plugin = m_auditioningPlugin; |
1316 if (!plugin) return; | 1314 if (!plugin) return; |
1317 | 1315 |
1357 AudioCallbackPlaySource::fillBuffers() | 1355 AudioCallbackPlaySource::fillBuffers() |
1358 { | 1356 { |
1359 static float *tmp = 0; | 1357 static float *tmp = 0; |
1360 static int tmpSize = 0; | 1358 static int tmpSize = 0; |
1361 | 1359 |
1362 int space = 0; | 1360 sv_frame_t space = 0; |
1363 for (int c = 0; c < getTargetChannelCount(); ++c) { | 1361 for (int c = 0; c < getTargetChannelCount(); ++c) { |
1364 RingBuffer<float> *wb = getWriteRingBuffer(c); | 1362 RingBuffer<float> *wb = getWriteRingBuffer(c); |
1365 if (wb) { | 1363 if (wb) { |
1366 int spaceHere = wb->getWriteSpace(); | 1364 sv_frame_t spaceHere = wb->getWriteSpace(); |
1367 if (c == 0 || spaceHere < space) space = spaceHere; | 1365 if (c == 0 || spaceHere < space) space = spaceHere; |
1368 } | 1366 } |
1369 } | 1367 } |
1370 | 1368 |
1371 if (space == 0) { | 1369 if (space == 0) { |
1373 cout << "AudioCallbackPlaySourceFillThread: no space to fill" << endl; | 1371 cout << "AudioCallbackPlaySourceFillThread: no space to fill" << endl; |
1374 #endif | 1372 #endif |
1375 return false; | 1373 return false; |
1376 } | 1374 } |
1377 | 1375 |
1378 int f = m_writeBufferFill; | 1376 sv_frame_t f = m_writeBufferFill; |
1379 | 1377 |
1380 bool readWriteEqual = (m_readBuffers == m_writeBuffers); | 1378 bool readWriteEqual = (m_readBuffers == m_writeBuffers); |
1381 | 1379 |
1382 #ifdef DEBUG_AUDIO_PLAY_SOURCE | 1380 #ifdef DEBUG_AUDIO_PLAY_SOURCE |
1383 if (!readWriteEqual) { | 1381 if (!readWriteEqual) { |
1396 cout << (resample ? "" : "not ") << "resampling (source " << getSourceSampleRate() << ", target " << getTargetSampleRate() << ")" << endl; | 1394 cout << (resample ? "" : "not ") << "resampling (source " << getSourceSampleRate() << ", target " << getTargetSampleRate() << ")" << endl; |
1397 #endif | 1395 #endif |
1398 | 1396 |
1399 int channels = getTargetChannelCount(); | 1397 int channels = getTargetChannelCount(); |
1400 | 1398 |
1401 int orig = space; | 1399 sv_frame_t orig = space; |
1402 int got = 0; | 1400 sv_frame_t got = 0; |
1403 | 1401 |
1404 static float **bufferPtrs = 0; | 1402 static float **bufferPtrs = 0; |
1405 static int bufferPtrCount = 0; | 1403 static int bufferPtrCount = 0; |
1406 | 1404 |
1407 if (bufferPtrCount < channels) { | 1405 if (bufferPtrCount < channels) { |
1578 } | 1576 } |
1579 | 1577 |
1580 return true; | 1578 return true; |
1581 } | 1579 } |
1582 | 1580 |
1583 int | 1581 sv_frame_t |
1584 AudioCallbackPlaySource::mixModels(int &frame, int count, float **buffers) | 1582 AudioCallbackPlaySource::mixModels(sv_frame_t &frame, sv_frame_t count, float **buffers) |
1585 { | 1583 { |
1586 int processed = 0; | 1584 sv_frame_t processed = 0; |
1587 int chunkStart = frame; | 1585 sv_frame_t chunkStart = frame; |
1588 int chunkSize = count; | 1586 sv_frame_t chunkSize = count; |
1589 int selectionSize = 0; | 1587 sv_frame_t selectionSize = 0; |
1590 int nextChunkStart = chunkStart + chunkSize; | 1588 sv_frame_t nextChunkStart = chunkStart + chunkSize; |
1591 | 1589 |
1592 bool looping = m_viewManager->getPlayLoopMode(); | 1590 bool looping = m_viewManager->getPlayLoopMode(); |
1593 bool constrained = (m_viewManager->getPlaySelectionMode() && | 1591 bool constrained = (m_viewManager->getPlaySelectionMode() && |
1594 !m_viewManager->getSelections().empty()); | 1592 !m_viewManager->getSelections().empty()); |
1595 | 1593 |
1615 | 1613 |
1616 chunkSize = count - processed; | 1614 chunkSize = count - processed; |
1617 nextChunkStart = chunkStart + chunkSize; | 1615 nextChunkStart = chunkStart + chunkSize; |
1618 selectionSize = 0; | 1616 selectionSize = 0; |
1619 | 1617 |
1620 int fadeIn = 0, fadeOut = 0; | 1618 sv_frame_t fadeIn = 0, fadeOut = 0; |
1621 | 1619 |
1622 if (constrained) { | 1620 if (constrained) { |
1623 | 1621 |
1624 int rChunkStart = | 1622 sv_frame_t rChunkStart = |
1625 m_viewManager->alignPlaybackFrameToReference(chunkStart); | 1623 m_viewManager->alignPlaybackFrameToReference(chunkStart); |
1626 | 1624 |
1627 Selection selection = | 1625 Selection selection = |
1628 m_viewManager->getContainingSelection(rChunkStart, true); | 1626 m_viewManager->getContainingSelection(rChunkStart, true); |
1629 | 1627 |
1641 chunkSize = 0; | 1639 chunkSize = 0; |
1642 nextChunkStart = chunkStart; | 1640 nextChunkStart = chunkStart; |
1643 | 1641 |
1644 } else { | 1642 } else { |
1645 | 1643 |
1646 int sf = m_viewManager->alignReferenceToPlaybackFrame | 1644 sv_frame_t sf = m_viewManager->alignReferenceToPlaybackFrame |
1647 (selection.getStartFrame()); | 1645 (selection.getStartFrame()); |
1648 int ef = m_viewManager->alignReferenceToPlaybackFrame | 1646 sv_frame_t ef = m_viewManager->alignReferenceToPlaybackFrame |
1649 (selection.getEndFrame()); | 1647 (selection.getEndFrame()); |
1650 | 1648 |
1651 selectionSize = ef - sf; | 1649 selectionSize = ef - sf; |
1652 | 1650 |
1653 if (chunkStart < sf) { | 1651 if (chunkStart < sf) { |