Mercurial > hg > svapp
diff 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 |
line wrap: on
line diff
--- a/audioio/AudioGenerator.cpp Thu Jan 24 11:03:59 2008 +0000 +++ b/audioio/AudioGenerator.cpp Thu Jan 24 14:35:43 2008 +0000 @@ -434,23 +434,60 @@ float **buffer, float gain, float pan, size_t fadeIn, size_t fadeOut) { - static float *channelBuffer = 0; - static size_t channelBufSiz = 0; + static float **channelBuffer = 0; + static size_t channelBufSiz = 0; + static size_t channelBufCount = 0; size_t totalFrames = frames + fadeIn/2 + fadeOut/2; - if (channelBufSiz < totalFrames) { + size_t modelChannels = dtvm->getChannelCount(); + + if (channelBufSiz < totalFrames || channelBufCount < modelChannels) { + + for (size_t c = 0; c < channelBufCount; ++c) { + delete[] channelBuffer[c]; + } + delete[] channelBuffer; - channelBuffer = new float[totalFrames]; + channelBuffer = new float *[modelChannels]; + + for (size_t c = 0; c < modelChannels; ++c) { + channelBuffer[c] = new float[totalFrames]; + } + + channelBufCount = modelChannels; channelBufSiz = totalFrames; } - + size_t got = 0; - size_t prevChannel = 999; + + if (startFrame >= fadeIn/2) { + got = dtvm->getData(0, modelChannels - 1, + startFrame - fadeIn/2, + frames + fadeOut/2 + fadeIn/2, + channelBuffer); + } else { + size_t missing = fadeIn/2 - startFrame; + + for (size_t c = 0; c < modelChannels; ++c) { + channelBuffer[c] += missing; + } + + got = dtvm->getData(0, modelChannels - 1, + startFrame, + frames + fadeOut/2, + channelBuffer); + + for (size_t c = 0; c < modelChannels; ++c) { + channelBuffer[c] -= missing; + } + + got += missing; + } for (size_t c = 0; c < m_targetChannelCount; ++c) { - size_t sourceChannel = (c % dtvm->getChannelCount()); + size_t sourceChannel = (c % modelChannels); // std::cerr << "mixing channel " << c << " from source channel " << sourceChannel << std::endl; @@ -463,28 +500,10 @@ } } - if (prevChannel != sourceChannel) { - if (startFrame >= fadeIn/2) { - got = dtvm->getData - (sourceChannel, - startFrame - fadeIn/2, - frames + fadeOut/2 + fadeIn/2, - channelBuffer); - } else { - size_t missing = fadeIn/2 - startFrame; - got = dtvm->getData - (sourceChannel, - startFrame, - frames + fadeOut/2, - channelBuffer + missing); - } - } - prevChannel = sourceChannel; - for (size_t i = 0; i < fadeIn/2; ++i) { float *back = buffer[c]; back -= fadeIn/2; - back[i] += (channelGain * channelBuffer[i] * i) / fadeIn; + back[i] += (channelGain * channelBuffer[sourceChannel][i] * i) / fadeIn; } for (size_t i = 0; i < frames + fadeOut/2; ++i) { @@ -495,7 +514,9 @@ if (i > frames - fadeOut/2) { mult = (mult * ((frames + fadeOut/2) - i)) / fadeOut; } - buffer[c][i] += mult * channelBuffer[i]; + float val = channelBuffer[sourceChannel][i]; + if (i >= got) val = 0.f; + buffer[c][i] += mult * val; } }