comparison audioio/AudioGenerator.cpp @ 235:1fcee2a1c03e sonification

Add queueExampleNote method to AudioCallbackPlaySource, providing a way to add a note to a special model which is mixed in outside of the normal playback flow. Currently mixing & generation happen in the play thread, which doesn't work very well -- buffer pending.
author Chris Cannam
date Fri, 24 Jun 2011 16:44:02 +0100
parents a98f1638c5ec
children a99de38af73f
comparison
equal deleted inserted replaced
234:a98f1638c5ec 235:1fcee2a1c03e
499 } 499 }
500 500
501 AudioGenerator::Notes 501 AudioGenerator::Notes
502 AudioGenerator::getNotesFromModel(Model *model, 502 AudioGenerator::getNotesFromModel(Model *model,
503 size_t startFrame, 503 size_t startFrame,
504 size_t frameCount) 504 size_t frameCount,
505 size_t latency)
505 { 506 {
506 Notes notes; 507 Notes notes;
507 508
508 Note n; 509 Note n;
509 n.pitch = 64; 510 n.pitch = 64;
514 qobject_cast<SparseOneDimensionalModel *>(model); 515 qobject_cast<SparseOneDimensionalModel *>(model);
515 516
516 if (sodm) { 517 if (sodm) {
517 518
518 SparseOneDimensionalModel::PointList points = 519 SparseOneDimensionalModel::PointList points =
519 sodm->getPoints(startFrame, startFrame + frameCount); 520 sodm->getPoints(startFrame + latency,
521 startFrame + frameCount + latency);
520 522
521 for (SparseOneDimensionalModel::PointList::iterator pli = 523 for (SparseOneDimensionalModel::PointList::iterator pli =
522 points.begin(); pli != points.end(); ++pli) { 524 points.begin(); pli != points.end(); ++pli) {
523 n.frame = pli->frame; 525 size_t frame = pli->frame;
526 if (frame > latency) frame -= latency;
527 if (frame < startFrame || frame >= startFrame + frameCount) {
528 continue;
529 }
530 n.frame = frame;
524 notes.push_back(n); 531 notes.push_back(n);
525 } 532 }
526 } 533 }
527 534
528 NoteModel *nm = 535 NoteModel *nm =
529 qobject_cast<NoteModel *>(model); 536 qobject_cast<NoteModel *>(model);
530 537
531 if (nm) { 538 if (nm) {
532 539
533 NoteModel::PointList points = 540 NoteModel::PointList points =
534 nm->getPoints(startFrame, startFrame + frameCount); 541 nm->getPoints(startFrame + latency,
542 startFrame + frameCount + latency);
535 543
536 for (NoteModel::PointList::iterator pli = 544 for (NoteModel::PointList::iterator pli =
537 points.begin(); pli != points.end(); ++pli) { 545 points.begin(); pli != points.end(); ++pli) {
538 546
539 n.frame = pli->frame; 547 size_t frame = pli->frame;
548 if (frame > latency) frame -= latency;
549 if (frame < startFrame || frame >= startFrame + frameCount) {
550 continue;
551 }
552
553 n.frame = frame;
540 n.duration = pli->duration; 554 n.duration = pli->duration;
541 if (n.duration == 1) n.duration = m_sourceSampleRate / 20; 555 if (n.duration == 1) n.duration = m_sourceSampleRate / 20;
542 556
543 if (nm->getScaleUnits() == "Hz") { 557 if (nm->getScaleUnits() == "Hz") {
544 n.pitch = Pitch::getPitchForFrequency(pli->value); 558 n.pitch = Pitch::getPitchForFrequency(pli->value);
563 float **buffer, float gain, float pan, 577 float **buffer, float gain, float pan,
564 size_t /* fadeIn */, 578 size_t /* fadeIn */,
565 size_t /* fadeOut */) 579 size_t /* fadeOut */)
566 { 580 {
567 RealTimePluginInstance *plugin = m_synthMap[model]; 581 RealTimePluginInstance *plugin = m_synthMap[model];
568 if (!plugin) return 0; 582 if (!plugin) {
583 SVDEBUG << "AudioGenerator::mixSparseModel: No plugin" << endl;
584 return 0;
585 }
586
587 SVDEBUG << "AudioGenerator::mixSparseModel: Have plugin" << endl;
569 588
570 size_t latency = plugin->getLatency(); 589 size_t latency = plugin->getLatency();
571 size_t blocks = frames / m_pluginBlockSize; 590 size_t blocks = frames / m_pluginBlockSize;
572 591
573 //!!! hang on -- the fact that the audio callback play source's 592 //!!! hang on -- the fact that the audio callback play source's
606 625
607 Vamp::RealTime blockTime = Vamp::RealTime::frame2RealTime 626 Vamp::RealTime blockTime = Vamp::RealTime::frame2RealTime
608 (startFrame + i * m_pluginBlockSize, m_sourceSampleRate); 627 (startFrame + i * m_pluginBlockSize, m_sourceSampleRate);
609 628
610 Notes notes = getNotesFromModel 629 Notes notes = getNotesFromModel
611 (model, reqStart + latency, m_pluginBlockSize); 630 (model, reqStart, m_pluginBlockSize, latency);
612 631
613 for (Notes::const_iterator ni = notes.begin(); ni != notes.end(); ++ni) { 632 for (Notes::const_iterator ni = notes.begin(); ni != notes.end(); ++ni) {
614 633
615 size_t frame = ni->frame; 634 size_t frame = ni->frame;
616 if (frame > latency) frame -= latency;
617
618 if (frame < reqStart ||
619 frame >= reqStart + m_pluginBlockSize) {
620 continue;
621 }
622 635
623 while (noteOffs.begin() != noteOffs.end() && 636 while (noteOffs.begin() != noteOffs.end() &&
624 noteOffs.begin()->frame <= frame) { 637 noteOffs.begin()->frame <= frame) {
625 638
626 Vamp::RealTime eventTime = Vamp::RealTime::frame2RealTime 639 Vamp::RealTime eventTime = Vamp::RealTime::frame2RealTime