comparison audioio/AudioGenerator.cpp @ 441:aa6fb3516e28 tonioni

Merge from cxx11 branch
author Chris Cannam
date Mon, 23 Mar 2015 11:26:28 +0000
parents 8d2112977aa0 72c662fe7ea3
children 88ae0e53a5da
comparison
equal deleted inserted replaced
440:2185d52b4758 441:aa6fb3516e28
35 #include <cmath> 35 #include <cmath>
36 36
37 #include <QDir> 37 #include <QDir>
38 #include <QFile> 38 #include <QFile>
39 39
40 const int 40 const sv_frame_t
41 AudioGenerator::m_processingBlockSize = 1024; 41 AudioGenerator::m_processingBlockSize = 1024;
42 42
43 QString 43 QString
44 AudioGenerator::m_sampleDir = ""; 44 AudioGenerator::m_sampleDir = "";
45 45
226 226
227 ClipMixer *mixer = new ClipMixer(m_targetChannelCount, 227 ClipMixer *mixer = new ClipMixer(m_targetChannelCount,
228 m_sourceSampleRate, 228 m_sourceSampleRate,
229 m_processingBlockSize); 229 m_processingBlockSize);
230 230
231 float clipF0 = Pitch::getFrequencyForPitch(60, 0, 440.0f); // required 231 double clipF0 = Pitch::getFrequencyForPitch(60, 0, 440.0); // required
232 232
233 QString clipPath = QString("%1/%2.wav").arg(m_sampleDir).arg(clipId); 233 QString clipPath = QString("%1/%2.wav").arg(m_sampleDir).arg(clipId);
234 234
235 float level = wantsQuieterClips(model) ? 0.5 : 1.0; 235 double level = wantsQuieterClips(model) ? 0.5 : 1.0;
236 if (!mixer->loadClipData(clipPath, clipF0, level)) { 236 if (!mixer->loadClipData(clipPath, clipF0, level)) {
237 delete mixer; 237 delete mixer;
238 return 0; 238 return 0;
239 } 239 }
240 240
316 for (ClipMixerMap::iterator i = m_clipMixerMap.begin(); i != m_clipMixerMap.end(); ++i) { 316 for (ClipMixerMap::iterator i = m_clipMixerMap.begin(); i != m_clipMixerMap.end(); ++i) {
317 if (i->second) i->second->setChannelCount(targetChannelCount); 317 if (i->second) i->second->setChannelCount(targetChannelCount);
318 } 318 }
319 } 319 }
320 320
321 int 321 sv_frame_t
322 AudioGenerator::getBlockSize() const 322 AudioGenerator::getBlockSize() const
323 { 323 {
324 return m_processingBlockSize; 324 return m_processingBlockSize;
325 } 325 }
326 326
340 340
341 m_soloModelSet.clear(); 341 m_soloModelSet.clear();
342 m_soloing = false; 342 m_soloing = false;
343 } 343 }
344 344
345 int 345 sv_frame_t
346 AudioGenerator::mixModel(Model *model, int startFrame, int frameCount, 346 AudioGenerator::mixModel(Model *model, sv_frame_t startFrame, sv_frame_t frameCount,
347 float **buffer, int fadeIn, int fadeOut) 347 float **buffer, sv_frame_t fadeIn, sv_frame_t fadeOut)
348 { 348 {
349 if (m_sourceSampleRate == 0) { 349 if (m_sourceSampleRate == 0) {
350 cerr << "WARNING: AudioGenerator::mixModel: No base source sample rate available" << endl; 350 cerr << "WARNING: AudioGenerator::mixModel: No base source sample rate available" << endl;
351 return frameCount; 351 return frameCount;
352 } 352 }
399 std::cerr << "AudioGenerator::mixModel: WARNING: Model " << model << " of type " << model->getTypeName() << " is marked as playable, but I have no mechanism to play it" << std::endl; 399 std::cerr << "AudioGenerator::mixModel: WARNING: Model " << model << " of type " << model->getTypeName() << " is marked as playable, but I have no mechanism to play it" << std::endl;
400 400
401 return frameCount; 401 return frameCount;
402 } 402 }
403 403
404 int 404 sv_frame_t
405 AudioGenerator::mixDenseTimeValueModel(DenseTimeValueModel *dtvm, 405 AudioGenerator::mixDenseTimeValueModel(DenseTimeValueModel *dtvm,
406 int startFrame, int frames, 406 sv_frame_t startFrame, sv_frame_t frames,
407 float **buffer, float gain, float pan, 407 float **buffer, float gain, float pan,
408 int fadeIn, int fadeOut) 408 sv_frame_t fadeIn, sv_frame_t fadeOut)
409 { 409 {
410 int maxFrames = frames + std::max(fadeIn, fadeOut); 410 sv_frame_t maxFrames = frames + std::max(fadeIn, fadeOut);
411 411
412 int modelChannels = dtvm->getChannelCount(); 412 int modelChannels = dtvm->getChannelCount();
413 413
414 if (m_channelBufSiz < maxFrames || m_channelBufCount < modelChannels) { 414 if (m_channelBufSiz < maxFrames || m_channelBufCount < modelChannels) {
415 415
426 426
427 m_channelBufCount = modelChannels; 427 m_channelBufCount = modelChannels;
428 m_channelBufSiz = maxFrames; 428 m_channelBufSiz = maxFrames;
429 } 429 }
430 430
431 int got = 0; 431 sv_frame_t got = 0;
432 432
433 if (startFrame >= fadeIn/2) { 433 if (startFrame >= fadeIn/2) {
434 got = dtvm->getData(0, modelChannels - 1, 434 got = dtvm->getData(0, modelChannels - 1,
435 startFrame - fadeIn/2, 435 startFrame - fadeIn/2,
436 frames + fadeOut/2 + fadeIn/2, 436 frames + fadeOut/2 + fadeIn/2,
437 m_channelBuffer); 437 m_channelBuffer);
438 } else { 438 } else {
439 int missing = fadeIn/2 - startFrame; 439 sv_frame_t missing = fadeIn/2 - startFrame;
440 440
441 for (int c = 0; c < modelChannels; ++c) { 441 for (int c = 0; c < modelChannels; ++c) {
442 m_channelBuffer[c] += missing; 442 m_channelBuffer[c] += missing;
443 } 443 }
444 444
468 // SVDEBUG << "mixing channel " << c << " from source channel " << sourceChannel << endl; 468 // SVDEBUG << "mixing channel " << c << " from source channel " << sourceChannel << endl;
469 469
470 float channelGain = gain; 470 float channelGain = gain;
471 if (pan != 0.0) { 471 if (pan != 0.0) {
472 if (c == 0) { 472 if (c == 0) {
473 if (pan > 0.0) channelGain *= 1.0 - pan; 473 if (pan > 0.0) channelGain *= 1.0f - pan;
474 } else { 474 } else {
475 if (pan < 0.0) channelGain *= pan + 1.0; 475 if (pan < 0.0) channelGain *= pan + 1.0f;
476 } 476 }
477 } 477 }
478 478
479 for (int i = 0; i < fadeIn/2; ++i) { 479 for (sv_frame_t i = 0; i < fadeIn/2; ++i) {
480 float *back = buffer[c]; 480 float *back = buffer[c];
481 back -= fadeIn/2; 481 back -= fadeIn/2;
482 back[i] += (channelGain * m_channelBuffer[sourceChannel][i] * i) / fadeIn; 482 back[i] +=
483 (channelGain * m_channelBuffer[sourceChannel][i] * float(i))
484 / float(fadeIn);
483 } 485 }
484 486
485 for (int i = 0; i < frames + fadeOut/2; ++i) { 487 for (sv_frame_t i = 0; i < frames + fadeOut/2; ++i) {
486 float mult = channelGain; 488 float mult = channelGain;
487 if (i < fadeIn/2) { 489 if (i < fadeIn/2) {
488 mult = (mult * i) / fadeIn; 490 mult = (mult * float(i)) / float(fadeIn);
489 } 491 }
490 if (i > frames - fadeOut/2) { 492 if (i > frames - fadeOut/2) {
491 mult = (mult * ((frames + fadeOut/2) - i)) / fadeOut; 493 mult = (mult * float((frames + fadeOut/2) - i)) / float(fadeOut);
492 } 494 }
493 float val = m_channelBuffer[sourceChannel][i]; 495 float val = m_channelBuffer[sourceChannel][i];
494 if (i >= got) val = 0.f; 496 if (i >= got) val = 0.f;
495 buffer[c][i] += mult * val; 497 buffer[c][i] += mult * val;
496 } 498 }
497 } 499 }
498 500
499 return got; 501 return got;
500 } 502 }
501 503
502 int 504 sv_frame_t
503 AudioGenerator::mixClipModel(Model *model, 505 AudioGenerator::mixClipModel(Model *model,
504 int startFrame, int frames, 506 sv_frame_t startFrame, sv_frame_t frames,
505 float **buffer, float gain, float pan) 507 float **buffer, float gain, float pan)
506 { 508 {
507 ClipMixer *clipMixer = m_clipMixerMap[model]; 509 ClipMixer *clipMixer = m_clipMixerMap[model];
508 if (!clipMixer) return 0; 510 if (!clipMixer) return 0;
509 511
510 int blocks = frames / m_processingBlockSize; 512 int blocks = int(frames / m_processingBlockSize);
511 513
512 //!!! todo: the below -- it matters 514 //!!! todo: the below -- it matters
513 515
514 //!!! hang on -- the fact that the audio callback play source's 516 //!!! hang on -- the fact that the audio callback play source's
515 //buffer is a multiple of the plugin's buffer size doesn't mean 517 //buffer is a multiple of the plugin's buffer size doesn't mean
519 //always have a multiple of the plugin buffer size? I guess this 521 //always have a multiple of the plugin buffer size? I guess this
520 //class has to be queryable for the plugin buffer size & the 522 //class has to be queryable for the plugin buffer size & the
521 //callback play source has to use that as a multiple for all the 523 //callback play source has to use that as a multiple for all the
522 //calls to mixModel 524 //calls to mixModel
523 525
524 int got = blocks * m_processingBlockSize; 526 sv_frame_t got = blocks * m_processingBlockSize;
525 527
526 #ifdef DEBUG_AUDIO_GENERATOR 528 #ifdef DEBUG_AUDIO_GENERATOR
527 cout << "mixModel [clip]: frames " << frames 529 cout << "mixModel [clip]: frames " << frames
528 << ", blocks " << blocks << endl; 530 << ", blocks " << blocks << endl;
529 #endif 531 #endif
535 537
536 float **bufferIndexes = new float *[m_targetChannelCount]; 538 float **bufferIndexes = new float *[m_targetChannelCount];
537 539
538 for (int i = 0; i < blocks; ++i) { 540 for (int i = 0; i < blocks; ++i) {
539 541
540 int reqStart = startFrame + i * m_processingBlockSize; 542 sv_frame_t reqStart = startFrame + i * m_processingBlockSize;
541 543
542 NoteList notes; 544 NoteList notes;
543 NoteExportable *exportable = dynamic_cast<NoteExportable *>(model); 545 NoteExportable *exportable = dynamic_cast<NoteExportable *>(model);
544 if (exportable) { 546 if (exportable) {
545 notes = exportable->getNotesWithin(reqStart, 547 notes = exportable->getNotesWithin(reqStart,
550 std::vector<ClipMixer::NoteEnd> ends; 552 std::vector<ClipMixer::NoteEnd> ends;
551 553
552 for (NoteList::const_iterator ni = notes.begin(); 554 for (NoteList::const_iterator ni = notes.begin();
553 ni != notes.end(); ++ni) { 555 ni != notes.end(); ++ni) {
554 556
555 int noteFrame = ni->start; 557 sv_frame_t noteFrame = ni->start;
556 558
557 if (noteFrame < reqStart || 559 if (noteFrame < reqStart ||
558 noteFrame >= reqStart + m_processingBlockSize) continue; 560 noteFrame >= reqStart + m_processingBlockSize) continue;
559 561
560 while (noteOffs.begin() != noteOffs.end() && 562 while (noteOffs.begin() != noteOffs.end() &&
561 noteOffs.begin()->frame <= noteFrame) { 563 noteOffs.begin()->frame <= noteFrame) {
562 564
563 int eventFrame = noteOffs.begin()->frame; 565 sv_frame_t eventFrame = noteOffs.begin()->frame;
564 if (eventFrame < reqStart) eventFrame = reqStart; 566 if (eventFrame < reqStart) eventFrame = reqStart;
565 567
566 off.frameOffset = eventFrame - reqStart; 568 off.frameOffset = eventFrame - reqStart;
567 off.frequency = noteOffs.begin()->frequency; 569 off.frequency = noteOffs.begin()->frequency;
568 570
574 noteOffs.erase(noteOffs.begin()); 576 noteOffs.erase(noteOffs.begin());
575 } 577 }
576 578
577 on.frameOffset = noteFrame - reqStart; 579 on.frameOffset = noteFrame - reqStart;
578 on.frequency = ni->getFrequency(); 580 on.frequency = ni->getFrequency();
579 on.level = float(ni->velocity) / 127.0; 581 on.level = float(ni->velocity) / 127.0f;
580 on.pan = pan; 582 on.pan = pan;
581 583
582 #ifdef DEBUG_AUDIO_GENERATOR 584 #ifdef DEBUG_AUDIO_GENERATOR
583 cout << "mixModel [clip]: adding note at frame " << noteFrame << ", frame offset " << on.frameOffset << " frequency " << on.frequency << ", level " << on.level << endl; 585 cout << "mixModel [clip]: adding note at frame " << noteFrame << ", frame offset " << on.frameOffset << " frequency " << on.frequency << ", level " << on.level << endl;
584 #endif 586 #endif
589 } 591 }
590 592
591 while (noteOffs.begin() != noteOffs.end() && 593 while (noteOffs.begin() != noteOffs.end() &&
592 noteOffs.begin()->frame <= reqStart + m_processingBlockSize) { 594 noteOffs.begin()->frame <= reqStart + m_processingBlockSize) {
593 595
594 int eventFrame = noteOffs.begin()->frame; 596 sv_frame_t eventFrame = noteOffs.begin()->frame;
595 if (eventFrame < reqStart) eventFrame = reqStart; 597 if (eventFrame < reqStart) eventFrame = reqStart;
596 598
597 off.frameOffset = eventFrame - reqStart; 599 off.frameOffset = eventFrame - reqStart;
598 off.frequency = noteOffs.begin()->frequency; 600 off.frequency = noteOffs.begin()->frequency;
599 601
615 delete[] bufferIndexes; 617 delete[] bufferIndexes;
616 618
617 return got; 619 return got;
618 } 620 }
619 621
620 int 622 sv_frame_t
621 AudioGenerator::mixContinuousSynthModel(Model *model, 623 AudioGenerator::mixContinuousSynthModel(Model *model,
622 int startFrame, 624 sv_frame_t startFrame,
623 int frames, 625 sv_frame_t frames,
624 float **buffer, 626 float **buffer,
625 float gain, 627 float gain,
626 float pan) 628 float pan)
627 { 629 {
628 ContinuousSynth *synth = m_continuousSynthMap[model]; 630 ContinuousSynth *synth = m_continuousSynthMap[model];
630 632
631 // only type we support here at the moment 633 // only type we support here at the moment
632 SparseTimeValueModel *stvm = qobject_cast<SparseTimeValueModel *>(model); 634 SparseTimeValueModel *stvm = qobject_cast<SparseTimeValueModel *>(model);
633 if (stvm->getScaleUnits() != "Hz") return 0; 635 if (stvm->getScaleUnits() != "Hz") return 0;
634 636
635 int blocks = frames / m_processingBlockSize; 637 int blocks = int(frames / m_processingBlockSize);
636 638
637 //!!! todo: see comment in mixClipModel 639 //!!! todo: see comment in mixClipModel
638 640
639 int got = blocks * m_processingBlockSize; 641 sv_frame_t got = blocks * m_processingBlockSize;
640 642
641 #ifdef DEBUG_AUDIO_GENERATOR 643 #ifdef DEBUG_AUDIO_GENERATOR
642 cout << "mixModel [synth]: frames " << frames 644 cout << "mixModel [synth]: frames " << frames
643 << ", blocks " << blocks << endl; 645 << ", blocks " << blocks << endl;
644 #endif 646 #endif
645 647
646 float **bufferIndexes = new float *[m_targetChannelCount]; 648 float **bufferIndexes = new float *[m_targetChannelCount];
647 649
648 for (int i = 0; i < blocks; ++i) { 650 for (int i = 0; i < blocks; ++i) {
649 651
650 int reqStart = startFrame + i * m_processingBlockSize; 652 sv_frame_t reqStart = startFrame + i * m_processingBlockSize;
651 653
652 for (int c = 0; c < m_targetChannelCount; ++c) { 654 for (int c = 0; c < m_targetChannelCount; ++c) {
653 bufferIndexes[c] = buffer[c] + i * m_processingBlockSize; 655 bufferIndexes[c] = buffer[c] + i * m_processingBlockSize;
654 } 656 }
655 657