Mercurial > hg > svapp
comparison audioio/AudioCallbackPlaySource.cpp @ 60:7b71da2d0631
* Some work on correct alignment when moving panes during playback
* Overhaul alignment for playback frame values (view manager now always
refers to reference-timeline values, only the play source deals in
playback model timeline values)
* When making a selection, ensure the selection regions shown in other
panes (and used for playback constraints if appropriate) are aligned
correctly. This may be the coolest feature ever implemented in any
program ever.
author | Chris Cannam |
---|---|
date | Thu, 22 Nov 2007 14:17:19 +0000 |
parents | eb596ef12041 |
children | ae2627ac7db2 |
comparison
equal
deleted
inserted
replaced
59:bf1a53489ccc | 60:7b71da2d0631 |
---|---|
341 void | 341 void |
342 AudioCallbackPlaySource::play(size_t startFrame) | 342 AudioCallbackPlaySource::play(size_t startFrame) |
343 { | 343 { |
344 if (m_viewManager->getPlaySelectionMode() && | 344 if (m_viewManager->getPlaySelectionMode() && |
345 !m_viewManager->getSelections().empty()) { | 345 !m_viewManager->getSelections().empty()) { |
346 MultiSelection::SelectionList selections = m_viewManager->getSelections(); | 346 |
347 MultiSelection::SelectionList::iterator i = selections.begin(); | 347 startFrame = m_viewManager->constrainFrameToSelection(startFrame); |
348 if (i != selections.end()) { | 348 |
349 if (startFrame < i->getStartFrame()) { | |
350 startFrame = i->getStartFrame(); | |
351 } else { | |
352 MultiSelection::SelectionList::iterator j = selections.end(); | |
353 --j; | |
354 if (startFrame >= j->getEndFrame()) { | |
355 startFrame = i->getStartFrame(); | |
356 } | |
357 } | |
358 } | |
359 } else { | 349 } else { |
360 if (startFrame >= m_lastModelEndFrame) { | 350 if (startFrame >= m_lastModelEndFrame) { |
361 startFrame = 0; | 351 startFrame = 0; |
362 } | 352 } |
363 } | 353 } |
354 | |
355 std::cerr << "play(" << startFrame << ") -> playback model "; | |
356 | |
357 startFrame = m_viewManager->alignReferenceToPlaybackFrame(startFrame); | |
358 | |
359 std::cerr << startFrame << std::endl; | |
364 | 360 |
365 // The fill thread will automatically empty its buffers before | 361 // The fill thread will automatically empty its buffers before |
366 // starting again if we have not so far been playing, but not if | 362 // starting again if we have not so far been playing, but not if |
367 // we're just re-seeking. | 363 // we're just re-seeking. |
368 | 364 |
520 } | 516 } |
521 | 517 |
522 if (framePlaying > latency) framePlaying -= latency; | 518 if (framePlaying > latency) framePlaying -= latency; |
523 else framePlaying = 0; | 519 else framePlaying = 0; |
524 | 520 |
521 // std::cerr << "framePlaying = " << framePlaying << " -> reference "; | |
522 | |
523 framePlaying = m_viewManager->alignPlaybackFrameToReference(framePlaying); | |
524 | |
525 // std::cerr << framePlaying << std::endl; | |
526 | |
525 if (!constrained) { | 527 if (!constrained) { |
526 if (!looping && framePlaying > m_lastModelEndFrame) { | 528 if (!looping && framePlaying > m_lastModelEndFrame) { |
527 framePlaying = m_lastModelEndFrame; | 529 framePlaying = m_lastModelEndFrame; |
528 stop(); | 530 stop(); |
529 } | 531 } |
530 return framePlaying; | 532 return framePlaying; |
531 } | 533 } |
534 | |
535 bufferedFrame = m_viewManager->alignPlaybackFrameToReference(bufferedFrame); | |
532 | 536 |
533 MultiSelection::SelectionList selections = m_viewManager->getSelections(); | 537 MultiSelection::SelectionList selections = m_viewManager->getSelections(); |
534 MultiSelection::SelectionList::const_iterator i; | 538 MultiSelection::SelectionList::const_iterator i; |
535 | 539 |
536 // i = selections.begin(); | 540 // i = selections.begin(); |
1243 selectionSize = 0; | 1247 selectionSize = 0; |
1244 | 1248 |
1245 size_t fadeIn = 0, fadeOut = 0; | 1249 size_t fadeIn = 0, fadeOut = 0; |
1246 | 1250 |
1247 if (constrained) { | 1251 if (constrained) { |
1252 | |
1253 size_t rChunkStart = | |
1254 m_viewManager->alignPlaybackFrameToReference(chunkStart); | |
1248 | 1255 |
1249 Selection selection = | 1256 Selection selection = |
1250 m_viewManager->getContainingSelection(chunkStart, true); | 1257 m_viewManager->getContainingSelection(rChunkStart, true); |
1251 | 1258 |
1252 if (selection.isEmpty()) { | 1259 if (selection.isEmpty()) { |
1253 if (looping) { | 1260 if (looping) { |
1254 selection = *m_viewManager->getSelections().begin(); | 1261 selection = *m_viewManager->getSelections().begin(); |
1255 chunkStart = selection.getStartFrame(); | 1262 chunkStart = m_viewManager->alignReferenceToPlaybackFrame |
1263 (selection.getStartFrame()); | |
1256 fadeIn = 50; | 1264 fadeIn = 50; |
1257 } | 1265 } |
1258 } | 1266 } |
1259 | 1267 |
1260 if (selection.isEmpty()) { | 1268 if (selection.isEmpty()) { |
1262 chunkSize = 0; | 1270 chunkSize = 0; |
1263 nextChunkStart = chunkStart; | 1271 nextChunkStart = chunkStart; |
1264 | 1272 |
1265 } else { | 1273 } else { |
1266 | 1274 |
1267 selectionSize = | 1275 size_t sf = m_viewManager->alignReferenceToPlaybackFrame |
1268 selection.getEndFrame() - | 1276 (selection.getStartFrame()); |
1269 selection.getStartFrame(); | 1277 size_t ef = m_viewManager->alignReferenceToPlaybackFrame |
1270 | 1278 (selection.getEndFrame()); |
1271 if (chunkStart < selection.getStartFrame()) { | 1279 |
1272 chunkStart = selection.getStartFrame(); | 1280 selectionSize = ef - sf; |
1281 | |
1282 if (chunkStart < sf) { | |
1283 chunkStart = sf; | |
1273 fadeIn = 50; | 1284 fadeIn = 50; |
1274 } | 1285 } |
1275 | 1286 |
1276 nextChunkStart = chunkStart + chunkSize; | 1287 nextChunkStart = chunkStart + chunkSize; |
1277 | 1288 |
1278 if (nextChunkStart >= selection.getEndFrame()) { | 1289 if (nextChunkStart >= ef) { |
1279 nextChunkStart = selection.getEndFrame(); | 1290 nextChunkStart = ef; |
1280 fadeOut = 50; | 1291 fadeOut = 50; |
1281 } | 1292 } |
1282 | 1293 |
1283 chunkSize = nextChunkStart - chunkStart; | 1294 chunkSize = nextChunkStart - chunkStart; |
1284 } | 1295 } |