comparison audioio/AudioGenerator.cpp @ 450:d9d132c0e240 alignment_view

Merge from default branch
author Chris Cannam
date Mon, 20 Apr 2015 09:21:32 +0100
parents c48bc6ddfe17
children 3485d324c172
comparison
equal deleted inserted replaced
430:adfb2948fabf 450:d9d132c0e240
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
122 m_sourceSampleRate = model->getSampleRate(); 122 m_sourceSampleRate = model->getSampleRate();
123 return true; 123 return true;
124 } 124 }
125 } 125 }
126 126
127 const Playable *playable = model;
128 if (!playable || !playable->canPlay()) return 0;
129
130 PlayParameters *parameters =
131 PlayParameterRepository::getInstance()->getPlayParameters(playable);
132
133 bool willPlay = !parameters->isPlayMuted();
134
127 if (usesClipMixer(model)) { 135 if (usesClipMixer(model)) {
128 ClipMixer *mixer = makeClipMixerFor(model); 136 ClipMixer *mixer = makeClipMixerFor(model);
129 if (mixer) { 137 if (mixer) {
130 QMutexLocker locker(&m_mutex); 138 QMutexLocker locker(&m_mutex);
131 m_clipMixerMap[model] = mixer; 139 m_clipMixerMap[model] = mixer;
132 return true; 140 return willPlay;
133 } 141 }
134 } 142 }
135 143
136 if (usesContinuousSynth(model)) { 144 if (usesContinuousSynth(model)) {
137 ContinuousSynth *synth = makeSynthFor(model); 145 ContinuousSynth *synth = makeSynthFor(model);
138 if (synth) { 146 if (synth) {
139 QMutexLocker locker(&m_mutex); 147 QMutexLocker locker(&m_mutex);
140 m_continuousSynthMap[model] = synth; 148 m_continuousSynthMap[model] = synth;
141 return true; 149 return willPlay;
142 } 150 }
143 } 151 }
144 152
145 return false; 153 return false;
146 } 154 }
207 PlayParameterRepository::getInstance()->getPlayParameters(playable); 215 PlayParameterRepository::getInstance()->getPlayParameters(playable);
208 if (parameters) { 216 if (parameters) {
209 clipId = parameters->getPlayClipId(); 217 clipId = parameters->getPlayClipId();
210 } 218 }
211 219
220 #ifdef DEBUG_AUDIO_GENERATOR
212 std::cerr << "AudioGenerator::makeClipMixerFor(" << model << "): sample id = " << clipId << std::endl; 221 std::cerr << "AudioGenerator::makeClipMixerFor(" << model << "): sample id = " << clipId << std::endl;
222 #endif
213 223
214 if (clipId == "") { 224 if (clipId == "") {
215 SVDEBUG << "AudioGenerator::makeClipMixerFor(" << model << "): no sample, skipping" << endl; 225 SVDEBUG << "AudioGenerator::makeClipMixerFor(" << model << "): no sample, skipping" << endl;
216 return 0; 226 return 0;
217 } 227 }
218 228
219 ClipMixer *mixer = new ClipMixer(m_targetChannelCount, 229 ClipMixer *mixer = new ClipMixer(m_targetChannelCount,
220 m_sourceSampleRate, 230 m_sourceSampleRate,
221 m_processingBlockSize); 231 m_processingBlockSize);
222 232
223 float clipF0 = Pitch::getFrequencyForPitch(60, 0, 440.0f); // required 233 double clipF0 = Pitch::getFrequencyForPitch(60, 0, 440.0); // required
224 234
225 QString clipPath = QString("%1/%2.wav").arg(m_sampleDir).arg(clipId); 235 QString clipPath = QString("%1/%2.wav").arg(m_sampleDir).arg(clipId);
226 236
227 float level = wantsQuieterClips(model) ? 0.5 : 1.0; 237 double level = wantsQuieterClips(model) ? 0.5 : 1.0;
228 if (!mixer->loadClipData(clipPath, clipF0, level)) { 238 if (!mixer->loadClipData(clipPath, clipF0, level)) {
229 delete mixer; 239 delete mixer;
230 return 0; 240 return 0;
231 } 241 }
232 242
243 #ifdef DEBUG_AUDIO_GENERATOR
233 std::cerr << "AudioGenerator::makeClipMixerFor(" << model << "): loaded clip " << clipId << std::endl; 244 std::cerr << "AudioGenerator::makeClipMixerFor(" << model << "): loaded clip " << clipId << std::endl;
245 #endif
234 246
235 return mixer; 247 return mixer;
236 } 248 }
237 249
238 ContinuousSynth * 250 ContinuousSynth *
244 ContinuousSynth *synth = new ContinuousSynth(m_targetChannelCount, 256 ContinuousSynth *synth = new ContinuousSynth(m_targetChannelCount,
245 m_sourceSampleRate, 257 m_sourceSampleRate,
246 m_processingBlockSize, 258 m_processingBlockSize,
247 m_waveType); 259 m_waveType);
248 260
261 #ifdef DEBUG_AUDIO_GENERATOR
249 std::cerr << "AudioGenerator::makeSynthFor(" << model << "): created synth" << std::endl; 262 std::cerr << "AudioGenerator::makeSynthFor(" << model << "): created synth" << std::endl;
263 #endif
250 264
251 return synth; 265 return synth;
252 } 266 }
253 267
254 void 268 void
282 void 296 void
283 AudioGenerator::reset() 297 AudioGenerator::reset()
284 { 298 {
285 QMutexLocker locker(&m_mutex); 299 QMutexLocker locker(&m_mutex);
286 300
301 #ifdef DEBUG_AUDIO_GENERATOR
287 cerr << "AudioGenerator::reset()" << endl; 302 cerr << "AudioGenerator::reset()" << endl;
303 #endif
288 304
289 for (ClipMixerMap::iterator i = m_clipMixerMap.begin(); i != m_clipMixerMap.end(); ++i) { 305 for (ClipMixerMap::iterator i = m_clipMixerMap.begin(); i != m_clipMixerMap.end(); ++i) {
290 if (i->second) { 306 if (i->second) {
291 i->second->reset(); 307 i->second->reset();
292 } 308 }
308 for (ClipMixerMap::iterator i = m_clipMixerMap.begin(); i != m_clipMixerMap.end(); ++i) { 324 for (ClipMixerMap::iterator i = m_clipMixerMap.begin(); i != m_clipMixerMap.end(); ++i) {
309 if (i->second) i->second->setChannelCount(targetChannelCount); 325 if (i->second) i->second->setChannelCount(targetChannelCount);
310 } 326 }
311 } 327 }
312 328
313 int 329 sv_frame_t
314 AudioGenerator::getBlockSize() const 330 AudioGenerator::getBlockSize() const
315 { 331 {
316 return m_processingBlockSize; 332 return m_processingBlockSize;
317 } 333 }
318 334
332 348
333 m_soloModelSet.clear(); 349 m_soloModelSet.clear();
334 m_soloing = false; 350 m_soloing = false;
335 } 351 }
336 352
337 int 353 sv_frame_t
338 AudioGenerator::mixModel(Model *model, int startFrame, int frameCount, 354 AudioGenerator::mixModel(Model *model, sv_frame_t startFrame, sv_frame_t frameCount,
339 float **buffer, int fadeIn, int fadeOut) 355 float **buffer, sv_frame_t fadeIn, sv_frame_t fadeOut)
340 { 356 {
341 if (m_sourceSampleRate == 0) { 357 if (m_sourceSampleRate == 0) {
342 cerr << "WARNING: AudioGenerator::mixModel: No base source sample rate available" << endl; 358 cerr << "WARNING: AudioGenerator::mixModel: No base source sample rate available" << endl;
343 return frameCount; 359 return frameCount;
344 } 360 }
391 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; 407 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;
392 408
393 return frameCount; 409 return frameCount;
394 } 410 }
395 411
396 int 412 sv_frame_t
397 AudioGenerator::mixDenseTimeValueModel(DenseTimeValueModel *dtvm, 413 AudioGenerator::mixDenseTimeValueModel(DenseTimeValueModel *dtvm,
398 int startFrame, int frames, 414 sv_frame_t startFrame, sv_frame_t frames,
399 float **buffer, float gain, float pan, 415 float **buffer, float gain, float pan,
400 int fadeIn, int fadeOut) 416 sv_frame_t fadeIn, sv_frame_t fadeOut)
401 { 417 {
402 int maxFrames = frames + std::max(fadeIn, fadeOut); 418 sv_frame_t maxFrames = frames + std::max(fadeIn, fadeOut);
403 419
404 int modelChannels = dtvm->getChannelCount(); 420 int modelChannels = dtvm->getChannelCount();
405 421
406 if (m_channelBufSiz < maxFrames || m_channelBufCount < modelChannels) { 422 if (m_channelBufSiz < maxFrames || m_channelBufCount < modelChannels) {
407 423
418 434
419 m_channelBufCount = modelChannels; 435 m_channelBufCount = modelChannels;
420 m_channelBufSiz = maxFrames; 436 m_channelBufSiz = maxFrames;
421 } 437 }
422 438
423 int got = 0; 439 sv_frame_t got = 0;
424 440
425 if (startFrame >= fadeIn/2) { 441 if (startFrame >= fadeIn/2) {
426 got = dtvm->getData(0, modelChannels - 1, 442 got = dtvm->getData(0, modelChannels - 1,
427 startFrame - fadeIn/2, 443 startFrame - fadeIn/2,
428 frames + fadeOut/2 + fadeIn/2, 444 frames + fadeOut/2 + fadeIn/2,
429 m_channelBuffer); 445 m_channelBuffer);
430 } else { 446 } else {
431 int missing = fadeIn/2 - startFrame; 447 sv_frame_t missing = fadeIn/2 - startFrame;
432 448
433 for (int c = 0; c < modelChannels; ++c) { 449 for (int c = 0; c < modelChannels; ++c) {
434 m_channelBuffer[c] += missing; 450 m_channelBuffer[c] += missing;
435 } 451 }
436 452
460 // SVDEBUG << "mixing channel " << c << " from source channel " << sourceChannel << endl; 476 // SVDEBUG << "mixing channel " << c << " from source channel " << sourceChannel << endl;
461 477
462 float channelGain = gain; 478 float channelGain = gain;
463 if (pan != 0.0) { 479 if (pan != 0.0) {
464 if (c == 0) { 480 if (c == 0) {
465 if (pan > 0.0) channelGain *= 1.0 - pan; 481 if (pan > 0.0) channelGain *= 1.0f - pan;
466 } else { 482 } else {
467 if (pan < 0.0) channelGain *= pan + 1.0; 483 if (pan < 0.0) channelGain *= pan + 1.0f;
468 } 484 }
469 } 485 }
470 486
471 for (int i = 0; i < fadeIn/2; ++i) { 487 for (sv_frame_t i = 0; i < fadeIn/2; ++i) {
472 float *back = buffer[c]; 488 float *back = buffer[c];
473 back -= fadeIn/2; 489 back -= fadeIn/2;
474 back[i] += (channelGain * m_channelBuffer[sourceChannel][i] * i) / fadeIn; 490 back[i] +=
491 (channelGain * m_channelBuffer[sourceChannel][i] * float(i))
492 / float(fadeIn);
475 } 493 }
476 494
477 for (int i = 0; i < frames + fadeOut/2; ++i) { 495 for (sv_frame_t i = 0; i < frames + fadeOut/2; ++i) {
478 float mult = channelGain; 496 float mult = channelGain;
479 if (i < fadeIn/2) { 497 if (i < fadeIn/2) {
480 mult = (mult * i) / fadeIn; 498 mult = (mult * float(i)) / float(fadeIn);
481 } 499 }
482 if (i > frames - fadeOut/2) { 500 if (i > frames - fadeOut/2) {
483 mult = (mult * ((frames + fadeOut/2) - i)) / fadeOut; 501 mult = (mult * float((frames + fadeOut/2) - i)) / float(fadeOut);
484 } 502 }
485 float val = m_channelBuffer[sourceChannel][i]; 503 float val = m_channelBuffer[sourceChannel][i];
486 if (i >= got) val = 0.f; 504 if (i >= got) val = 0.f;
487 buffer[c][i] += mult * val; 505 buffer[c][i] += mult * val;
488 } 506 }
489 } 507 }
490 508
491 return got; 509 return got;
492 } 510 }
493 511
494 int 512 sv_frame_t
495 AudioGenerator::mixClipModel(Model *model, 513 AudioGenerator::mixClipModel(Model *model,
496 int startFrame, int frames, 514 sv_frame_t startFrame, sv_frame_t frames,
497 float **buffer, float gain, float pan) 515 float **buffer, float gain, float pan)
498 { 516 {
499 ClipMixer *clipMixer = m_clipMixerMap[model]; 517 ClipMixer *clipMixer = m_clipMixerMap[model];
500 if (!clipMixer) return 0; 518 if (!clipMixer) return 0;
501 519
502 int blocks = frames / m_processingBlockSize; 520 int blocks = int(frames / m_processingBlockSize);
503 521
504 //!!! todo: the below -- it matters 522 //!!! todo: the below -- it matters
505 523
506 //!!! hang on -- the fact that the audio callback play source's 524 //!!! hang on -- the fact that the audio callback play source's
507 //buffer is a multiple of the plugin's buffer size doesn't mean 525 //buffer is a multiple of the plugin's buffer size doesn't mean
511 //always have a multiple of the plugin buffer size? I guess this 529 //always have a multiple of the plugin buffer size? I guess this
512 //class has to be queryable for the plugin buffer size & the 530 //class has to be queryable for the plugin buffer size & the
513 //callback play source has to use that as a multiple for all the 531 //callback play source has to use that as a multiple for all the
514 //calls to mixModel 532 //calls to mixModel
515 533
516 int got = blocks * m_processingBlockSize; 534 sv_frame_t got = blocks * m_processingBlockSize;
517 535
518 #ifdef DEBUG_AUDIO_GENERATOR 536 #ifdef DEBUG_AUDIO_GENERATOR
519 cout << "mixModel [clip]: frames " << frames 537 cout << "mixModel [clip]: start " << startFrame << ", frames " << frames
520 << ", blocks " << blocks << endl; 538 << ", blocks " << blocks << ", have " << m_noteOffs.size()
539 << " note-offs" << endl;
521 #endif 540 #endif
522 541
523 ClipMixer::NoteStart on; 542 ClipMixer::NoteStart on;
524 ClipMixer::NoteEnd off; 543 ClipMixer::NoteEnd off;
525 544
527 546
528 float **bufferIndexes = new float *[m_targetChannelCount]; 547 float **bufferIndexes = new float *[m_targetChannelCount];
529 548
530 for (int i = 0; i < blocks; ++i) { 549 for (int i = 0; i < blocks; ++i) {
531 550
532 int reqStart = startFrame + i * m_processingBlockSize; 551 sv_frame_t reqStart = startFrame + i * m_processingBlockSize;
533 552
534 NoteList notes; 553 NoteList notes;
535 NoteExportable *exportable = dynamic_cast<NoteExportable *>(model); 554 NoteExportable *exportable = dynamic_cast<NoteExportable *>(model);
536 if (exportable) { 555 if (exportable) {
537 notes = exportable->getNotesWithin(reqStart, 556 notes = exportable->getNotesWithin(reqStart,
542 std::vector<ClipMixer::NoteEnd> ends; 561 std::vector<ClipMixer::NoteEnd> ends;
543 562
544 for (NoteList::const_iterator ni = notes.begin(); 563 for (NoteList::const_iterator ni = notes.begin();
545 ni != notes.end(); ++ni) { 564 ni != notes.end(); ++ni) {
546 565
547 int noteFrame = ni->start; 566 sv_frame_t noteFrame = ni->start;
548 567
549 if (noteFrame < reqStart || 568 if (noteFrame < reqStart ||
550 noteFrame >= reqStart + m_processingBlockSize) continue; 569 noteFrame >= reqStart + m_processingBlockSize) continue;
551 570
552 while (noteOffs.begin() != noteOffs.end() && 571 while (noteOffs.begin() != noteOffs.end() &&
553 noteOffs.begin()->frame <= noteFrame) { 572 noteOffs.begin()->frame <= noteFrame) {
554 573
555 int eventFrame = noteOffs.begin()->frame; 574 sv_frame_t eventFrame = noteOffs.begin()->frame;
556 if (eventFrame < reqStart) eventFrame = reqStart; 575 if (eventFrame < reqStart) eventFrame = reqStart;
557 576
558 off.frameOffset = eventFrame - reqStart; 577 off.frameOffset = eventFrame - reqStart;
559 off.frequency = noteOffs.begin()->frequency; 578 off.frequency = noteOffs.begin()->frequency;
560 579
566 noteOffs.erase(noteOffs.begin()); 585 noteOffs.erase(noteOffs.begin());
567 } 586 }
568 587
569 on.frameOffset = noteFrame - reqStart; 588 on.frameOffset = noteFrame - reqStart;
570 on.frequency = ni->getFrequency(); 589 on.frequency = ni->getFrequency();
571 on.level = float(ni->velocity) / 127.0; 590 on.level = float(ni->velocity) / 127.0f;
572 on.pan = pan; 591 on.pan = pan;
573 592
574 #ifdef DEBUG_AUDIO_GENERATOR 593 #ifdef DEBUG_AUDIO_GENERATOR
575 cout << "mixModel [clip]: adding note at frame " << noteFrame << ", frame offset " << on.frameOffset << " frequency " << on.frequency << ", level " << on.level << endl; 594 cout << "mixModel [clip]: adding note at frame " << noteFrame << ", frame offset " << on.frameOffset << " frequency " << on.frequency << ", level " << on.level << endl;
576 #endif 595 #endif
581 } 600 }
582 601
583 while (noteOffs.begin() != noteOffs.end() && 602 while (noteOffs.begin() != noteOffs.end() &&
584 noteOffs.begin()->frame <= reqStart + m_processingBlockSize) { 603 noteOffs.begin()->frame <= reqStart + m_processingBlockSize) {
585 604
586 int eventFrame = noteOffs.begin()->frame; 605 sv_frame_t eventFrame = noteOffs.begin()->frame;
587 if (eventFrame < reqStart) eventFrame = reqStart; 606 if (eventFrame < reqStart) eventFrame = reqStart;
588 607
589 off.frameOffset = eventFrame - reqStart; 608 off.frameOffset = eventFrame - reqStart;
590 off.frequency = noteOffs.begin()->frequency; 609 off.frequency = noteOffs.begin()->frequency;
591 610
607 delete[] bufferIndexes; 626 delete[] bufferIndexes;
608 627
609 return got; 628 return got;
610 } 629 }
611 630
612 int 631 sv_frame_t
613 AudioGenerator::mixContinuousSynthModel(Model *model, 632 AudioGenerator::mixContinuousSynthModel(Model *model,
614 int startFrame, 633 sv_frame_t startFrame,
615 int frames, 634 sv_frame_t frames,
616 float **buffer, 635 float **buffer,
617 float gain, 636 float gain,
618 float pan) 637 float pan)
619 { 638 {
620 ContinuousSynth *synth = m_continuousSynthMap[model]; 639 ContinuousSynth *synth = m_continuousSynthMap[model];
622 641
623 // only type we support here at the moment 642 // only type we support here at the moment
624 SparseTimeValueModel *stvm = qobject_cast<SparseTimeValueModel *>(model); 643 SparseTimeValueModel *stvm = qobject_cast<SparseTimeValueModel *>(model);
625 if (stvm->getScaleUnits() != "Hz") return 0; 644 if (stvm->getScaleUnits() != "Hz") return 0;
626 645
627 int blocks = frames / m_processingBlockSize; 646 int blocks = int(frames / m_processingBlockSize);
628 647
629 //!!! todo: see comment in mixClipModel 648 //!!! todo: see comment in mixClipModel
630 649
631 int got = blocks * m_processingBlockSize; 650 sv_frame_t got = blocks * m_processingBlockSize;
632 651
633 #ifdef DEBUG_AUDIO_GENERATOR 652 #ifdef DEBUG_AUDIO_GENERATOR
634 cout << "mixModel [synth]: frames " << frames 653 cout << "mixModel [synth]: frames " << frames
635 << ", blocks " << blocks << endl; 654 << ", blocks " << blocks << endl;
636 #endif 655 #endif
637 656
638 float **bufferIndexes = new float *[m_targetChannelCount]; 657 float **bufferIndexes = new float *[m_targetChannelCount];
639 658
640 for (int i = 0; i < blocks; ++i) { 659 for (int i = 0; i < blocks; ++i) {
641 660
642 int reqStart = startFrame + i * m_processingBlockSize; 661 sv_frame_t reqStart = startFrame + i * m_processingBlockSize;
643 662
644 for (int c = 0; c < m_targetChannelCount; ++c) { 663 for (int c = 0; c < m_targetChannelCount; ++c) {
645 bufferIndexes[c] = buffer[c] + i * m_processingBlockSize; 664 bufferIndexes[c] = buffer[c] + i * m_processingBlockSize;
646 } 665 }
647 666