Mercurial > hg > svapp
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 |