comparison audioio/AudioGenerator.cpp @ 80:448ff6e34b99

* Add wave file model method for reading more than one channel at once, avoiding ludicrously expensive backward seeks and double-reads when playing multi-channel files or using them as inputs to feature extraction plugins
author Chris Cannam
date Thu, 24 Jan 2008 14:35:43 +0000
parents 215b8b1b0308
children e25e8f5d785b
comparison
equal deleted inserted replaced
79:b1a68403714b 80:448ff6e34b99
432 AudioGenerator::mixDenseTimeValueModel(DenseTimeValueModel *dtvm, 432 AudioGenerator::mixDenseTimeValueModel(DenseTimeValueModel *dtvm,
433 size_t startFrame, size_t frames, 433 size_t startFrame, size_t frames,
434 float **buffer, float gain, float pan, 434 float **buffer, float gain, float pan,
435 size_t fadeIn, size_t fadeOut) 435 size_t fadeIn, size_t fadeOut)
436 { 436 {
437 static float *channelBuffer = 0; 437 static float **channelBuffer = 0;
438 static size_t channelBufSiz = 0; 438 static size_t channelBufSiz = 0;
439 static size_t channelBufCount = 0;
439 440
440 size_t totalFrames = frames + fadeIn/2 + fadeOut/2; 441 size_t totalFrames = frames + fadeIn/2 + fadeOut/2;
441 442
442 if (channelBufSiz < totalFrames) { 443 size_t modelChannels = dtvm->getChannelCount();
444
445 if (channelBufSiz < totalFrames || channelBufCount < modelChannels) {
446
447 for (size_t c = 0; c < channelBufCount; ++c) {
448 delete[] channelBuffer[c];
449 }
450
443 delete[] channelBuffer; 451 delete[] channelBuffer;
444 channelBuffer = new float[totalFrames]; 452 channelBuffer = new float *[modelChannels];
453
454 for (size_t c = 0; c < modelChannels; ++c) {
455 channelBuffer[c] = new float[totalFrames];
456 }
457
458 channelBufCount = modelChannels;
445 channelBufSiz = totalFrames; 459 channelBufSiz = totalFrames;
446 } 460 }
447 461
448 size_t got = 0; 462 size_t got = 0;
449 size_t prevChannel = 999; 463
464 if (startFrame >= fadeIn/2) {
465 got = dtvm->getData(0, modelChannels - 1,
466 startFrame - fadeIn/2,
467 frames + fadeOut/2 + fadeIn/2,
468 channelBuffer);
469 } else {
470 size_t missing = fadeIn/2 - startFrame;
471
472 for (size_t c = 0; c < modelChannels; ++c) {
473 channelBuffer[c] += missing;
474 }
475
476 got = dtvm->getData(0, modelChannels - 1,
477 startFrame,
478 frames + fadeOut/2,
479 channelBuffer);
480
481 for (size_t c = 0; c < modelChannels; ++c) {
482 channelBuffer[c] -= missing;
483 }
484
485 got += missing;
486 }
450 487
451 for (size_t c = 0; c < m_targetChannelCount; ++c) { 488 for (size_t c = 0; c < m_targetChannelCount; ++c) {
452 489
453 size_t sourceChannel = (c % dtvm->getChannelCount()); 490 size_t sourceChannel = (c % modelChannels);
454 491
455 // std::cerr << "mixing channel " << c << " from source channel " << sourceChannel << std::endl; 492 // std::cerr << "mixing channel " << c << " from source channel " << sourceChannel << std::endl;
456 493
457 float channelGain = gain; 494 float channelGain = gain;
458 if (pan != 0.0) { 495 if (pan != 0.0) {
461 } else { 498 } else {
462 if (pan < 0.0) channelGain *= pan + 1.0; 499 if (pan < 0.0) channelGain *= pan + 1.0;
463 } 500 }
464 } 501 }
465 502
466 if (prevChannel != sourceChannel) {
467 if (startFrame >= fadeIn/2) {
468 got = dtvm->getData
469 (sourceChannel,
470 startFrame - fadeIn/2,
471 frames + fadeOut/2 + fadeIn/2,
472 channelBuffer);
473 } else {
474 size_t missing = fadeIn/2 - startFrame;
475 got = dtvm->getData
476 (sourceChannel,
477 startFrame,
478 frames + fadeOut/2,
479 channelBuffer + missing);
480 }
481 }
482 prevChannel = sourceChannel;
483
484 for (size_t i = 0; i < fadeIn/2; ++i) { 503 for (size_t i = 0; i < fadeIn/2; ++i) {
485 float *back = buffer[c]; 504 float *back = buffer[c];
486 back -= fadeIn/2; 505 back -= fadeIn/2;
487 back[i] += (channelGain * channelBuffer[i] * i) / fadeIn; 506 back[i] += (channelGain * channelBuffer[sourceChannel][i] * i) / fadeIn;
488 } 507 }
489 508
490 for (size_t i = 0; i < frames + fadeOut/2; ++i) { 509 for (size_t i = 0; i < frames + fadeOut/2; ++i) {
491 float mult = channelGain; 510 float mult = channelGain;
492 if (i < fadeIn/2) { 511 if (i < fadeIn/2) {
493 mult = (mult * i) / fadeIn; 512 mult = (mult * i) / fadeIn;
494 } 513 }
495 if (i > frames - fadeOut/2) { 514 if (i > frames - fadeOut/2) {
496 mult = (mult * ((frames + fadeOut/2) - i)) / fadeOut; 515 mult = (mult * ((frames + fadeOut/2) - i)) / fadeOut;
497 } 516 }
498 buffer[c][i] += mult * channelBuffer[i]; 517 float val = channelBuffer[sourceChannel][i];
518 if (i >= got) val = 0.f;
519 buffer[c][i] += mult * val;
499 } 520 }
500 } 521 }
501 522
502 return got; 523 return got;
503 } 524 }