Remove naked new[] in: mixer

This commit is contained in:
Paul Licameli 2016-04-14 11:54:59 -04:00
parent 0113e6f44f
commit ea05fac870
3 changed files with 76 additions and 112 deletions

View File

@ -244,18 +244,24 @@ Mixer::Mixer(const WaveTrackConstArray &inputTracks,
unsigned numOutChannels, size_t outBufferSize, bool outInterleaved,
double outRate, sampleFormat outFormat,
bool highQuality, MixerSpec *mixerSpec)
{
int i;
: mNumInputTracks { inputTracks.size() }
const auto numInputTracks = inputTracks.size();
// This is the number of samples grabbed in one go from a track
// and placed in a queue, when mixing with resampling.
// (Should we use WaveTrack::GetBestBlockSize instead?)
, mQueueMaxLen{ 65536 }
, mSampleQueue{ mNumInputTracks, mQueueMaxLen }
, mNumChannels{ static_cast<size_t>(numOutChannels) }
, mGains{ mNumChannels }
{
mHighQuality = highQuality;
mNumInputTracks = numInputTracks;
mInputTrack = new WaveTrackCache[mNumInputTracks];
mInputTrack.reinit(mNumInputTracks);
// mSamplePos holds for each track the next sample position not
// yet processed.
mSamplePos = new sampleCount[mNumInputTracks];
for(i=0; i<mNumInputTracks; i++) {
mSamplePos.reinit(mNumInputTracks);
for(size_t i=0; i<mNumInputTracks; i++) {
mInputTrack[i].SetTrack(inputTracks[i]);
mSamplePos[i] = inputTracks[i]->TimeToLongSamples(startTime);
}
@ -263,14 +269,12 @@ Mixer::Mixer(const WaveTrackConstArray &inputTracks,
mT0 = startTime;
mT1 = stopTime;
mTime = startTime;
mNumChannels = numOutChannels;
mBufferSize = outBufferSize;
mInterleaved = outInterleaved;
mRate = outRate;
mSpeed = 1.0;
mFormat = outFormat;
mApplyTrackGains = true;
mGains = new float[mNumChannels];
if( mixerSpec && mixerSpec->GetNumChannels() == mNumChannels &&
mixerSpec->GetNumTracks() == mNumInputTracks )
mMixerSpec = mixerSpec;
@ -286,18 +290,13 @@ Mixer::Mixer(const WaveTrackConstArray &inputTracks,
mInterleavedBufferSize = mBufferSize;
}
mBuffer = new SampleBuffer[mNumBuffers];
mTemp = new SampleBuffer[mNumBuffers];
mBuffer.reinit(mNumBuffers);
mTemp.reinit(mNumBuffers);
for (int c = 0; c < mNumBuffers; c++) {
mBuffer[c].Allocate(mInterleavedBufferSize, mFormat);
mTemp[c].Allocate(mInterleavedBufferSize, floatSample);
}
mFloatBuffer = new float[mInterleavedBufferSize];
// This is the number of samples grabbed in one go from a track
// and placed in a queue, when mixing with resampling.
// (Should we use WaveTrack::GetBestBlockSize instead?)
mQueueMaxLen = 65536;
mFloatBuffer = Floats{ mInterleavedBufferSize };
// But cut the queue into blocks of this finer size
// for variable rate resampling. Each block is resampled at some
@ -305,13 +304,12 @@ Mixer::Mixer(const WaveTrackConstArray &inputTracks,
mProcessLen = 1024;
// Position in each queue of the start of the next block to resample.
mQueueStart = new int[mNumInputTracks];
mQueueStart.reinit(mNumInputTracks);
// For each queue, the number of available samples after the queue start.
mQueueLen = new int[mNumInputTracks];
mSampleQueue = new float *[mNumInputTracks];
mResample = new Resample*[mNumInputTracks];
for(i=0; i<mNumInputTracks; i++) {
mQueueLen.reinit(mNumInputTracks);
mResample.reinit(mNumInputTracks);
for(size_t i=0; i<mNumInputTracks; i++) {
double factor = (mRate / mInputTrack[i].GetTrack()->GetRate());
double minFactor, maxFactor;
if (mTimeTrack) {
@ -332,36 +330,17 @@ Mixer::Mixer(const WaveTrackConstArray &inputTracks,
minFactor = maxFactor = factor;
}
mResample[i] = new Resample(mHighQuality, minFactor, maxFactor);
mSampleQueue[i] = new float[mQueueMaxLen];
mResample[i] = std::make_unique<Resample>(mHighQuality, minFactor, maxFactor);
mQueueStart[i] = 0;
mQueueLen[i] = 0;
}
const auto envLen = std::max(mQueueMaxLen, mInterleavedBufferSize);
mEnvValues = new double[envLen];
mEnvValues.reinit(envLen);
}
Mixer::~Mixer()
{
int i;
delete[] mBuffer;
delete[] mTemp;
delete[] mInputTrack;
delete[] mEnvValues;
delete[] mFloatBuffer;
delete[] mGains;
delete[] mSamplePos;
for(i=0; i<mNumInputTracks; i++) {
delete mResample[i];
delete[] mSampleQueue[i];
}
delete[] mResample;
delete[] mSampleQueue;
delete[] mQueueStart;
delete[] mQueueLen;
}
void Mixer::ApplyTrackGains(bool apply)
@ -461,7 +440,7 @@ size_t Mixer::MixVariableRates(int *channelFlags, WaveTrackCache &cache,
else
memset(&queue[*queueLen], 0, sizeof(float) * getLen);
track->GetEnvelopeValues(mEnvValues,
track->GetEnvelopeValues(mEnvValues.get(),
getLen,
(*pos - (getLen- 1)).as_double() / trackRate);
*pos -= getLen;
@ -473,7 +452,7 @@ size_t Mixer::MixVariableRates(int *channelFlags, WaveTrackCache &cache,
else
memset(&queue[*queueLen], 0, sizeof(float) * getLen);
track->GetEnvelopeValues(mEnvValues,
track->GetEnvelopeValues(mEnvValues.get(),
getLen,
(*pos).as_double() / trackRate);
@ -532,7 +511,7 @@ size_t Mixer::MixVariableRates(int *channelFlags, WaveTrackCache &cache,
}
}
for (int c = 0; c < mNumChannels; c++) {
for (size_t c = 0; c < mNumChannels; c++) {
if (mApplyTrackGains) {
mGains[c] = track->GetChannelGain(c);
}
@ -543,9 +522,9 @@ size_t Mixer::MixVariableRates(int *channelFlags, WaveTrackCache &cache,
MixBuffers(mNumChannels,
channelFlags,
mGains,
(samplePtr)mFloatBuffer,
mTemp,
mGains.get(),
(samplePtr)mFloatBuffer.get(),
mTemp.get(),
out,
mInterleaved);
@ -557,7 +536,6 @@ size_t Mixer::MixSameRate(int *channelFlags, WaveTrackCache &cache,
{
const WaveTrack *const track = cache.GetTrack();
auto slen = mMaxOut;
int c;
const double t = ( *pos ).as_double() / track->GetRate();
const double trackEndTime = track->GetEndTime();
const double trackStartTime = track->GetStartTime();
@ -578,37 +556,37 @@ size_t Mixer::MixSameRate(int *channelFlags, WaveTrackCache &cache,
if (backwards) {
auto results = cache.Get(floatSample, *pos - (slen - 1), slen);
if (results)
memcpy(mFloatBuffer, results, sizeof(float) * slen);
memcpy(mFloatBuffer.get(), results, sizeof(float) * slen);
else
memset(mFloatBuffer, 0, sizeof(float) * slen);
track->GetEnvelopeValues(mEnvValues, slen, t - (slen - 1) / mRate);
memset(mFloatBuffer.get(), 0, sizeof(float) * slen);
track->GetEnvelopeValues(mEnvValues.get(), slen, t - (slen - 1) / mRate);
for(decltype(slen) i = 0; i < slen; i++)
mFloatBuffer[i] *= mEnvValues[i]; // Track gain control will go here?
ReverseSamples((samplePtr)mFloatBuffer, floatSample, 0, slen);
ReverseSamples((samplePtr)mFloatBuffer.get(), floatSample, 0, slen);
*pos -= slen;
}
else {
auto results = cache.Get(floatSample, *pos, slen);
if (results)
memcpy(mFloatBuffer, results, sizeof(float) * slen);
memcpy(mFloatBuffer.get(), results, sizeof(float) * slen);
else
memset(mFloatBuffer, 0, sizeof(float) * slen);
track->GetEnvelopeValues(mEnvValues, slen, t);
memset(mFloatBuffer.get(), 0, sizeof(float) * slen);
track->GetEnvelopeValues(mEnvValues.get(), slen, t);
for(decltype(slen) i = 0; i < slen; i++)
mFloatBuffer[i] *= mEnvValues[i]; // Track gain control will go here?
*pos += slen;
}
for(c=0; c<mNumChannels; c++)
for(size_t c=0; c<mNumChannels; c++)
if (mApplyTrackGains)
mGains[c] = track->GetChannelGain(c);
else
mGains[c] = 1.0;
MixBuffers(mNumChannels, channelFlags, mGains,
(samplePtr)mFloatBuffer, mTemp, slen, mInterleaved);
MixBuffers(mNumChannels, channelFlags, mGains.get(),
(samplePtr)mFloatBuffer.get(), mTemp.get(), slen, mInterleaved);
return slen;
}
@ -620,28 +598,27 @@ size_t Mixer::Process(size_t maxToProcess)
//if (mT >= mT1)
// return 0;
int i, j;
decltype(Process(0)) maxOut = 0;
int *channelFlags = new int[mNumChannels];
ArrayOf<int> channelFlags{ mNumChannels };
mMaxOut = maxToProcess;
Clear();
for(i=0; i<mNumInputTracks; i++) {
for(size_t i=0; i<mNumInputTracks; i++) {
const WaveTrack *const track = mInputTrack[i].GetTrack();
for(j=0; j<mNumChannels; j++)
for(size_t j=0; j<mNumChannels; j++)
channelFlags[j] = 0;
if( mMixerSpec ) {
//ignore left and right when downmixing is not required
for( j = 0; j < mNumChannels; j++ )
for(size_t j = 0; j < mNumChannels; j++ )
channelFlags[ j ] = mMixerSpec->mMap[ i ][ j ] ? 1 : 0;
}
else {
switch(track->GetChannel()) {
case Track::MonoChannel:
default:
for(j=0; j<mNumChannels; j++)
for(size_t j=0; j<mNumChannels; j++)
channelFlags[j] = 1;
break;
case Track::LeftChannel:
@ -657,12 +634,12 @@ size_t Mixer::Process(size_t maxToProcess)
}
if (mbVariableRates || track->GetRate() != mRate)
maxOut = std::max(maxOut,
MixVariableRates(channelFlags, mInputTrack[i],
&mSamplePos[i], mSampleQueue[i],
&mQueueStart[i], &mQueueLen[i], mResample[i]));
MixVariableRates(channelFlags.get(), mInputTrack[i],
&mSamplePos[i], mSampleQueue[i].get(),
&mQueueStart[i], &mQueueLen[i], mResample[i].get()));
else
maxOut = std::max(maxOut,
MixSameRate(channelFlags, mInputTrack[i], &mSamplePos[i]));
MixSameRate(channelFlags.get(), mInputTrack[i], &mSamplePos[i]));
double t = mSamplePos[i].as_double() / (double)track->GetRate();
if (mT0 > mT1)
@ -673,7 +650,7 @@ size_t Mixer::Process(size_t maxToProcess)
mTime = std::min(std::max(t, mTime), mT1);
}
if(mInterleaved) {
for(int c=0; c<mNumChannels; c++) {
for(size_t c=0; c<mNumChannels; c++) {
CopySamples(mTemp[0].ptr() + (c * SAMPLE_SIZE(floatSample)),
floatSample,
mBuffer[0].ptr() + (c * SAMPLE_SIZE(mFormat)),
@ -685,7 +662,7 @@ size_t Mixer::Process(size_t maxToProcess)
}
}
else {
for(int c=0; c<mNumBuffers; c++) {
for(size_t c=0; c<mNumBuffers; c++) {
CopySamples(mTemp[c].ptr(),
floatSample,
mBuffer[c].ptr(),
@ -697,8 +674,6 @@ size_t Mixer::Process(size_t maxToProcess)
// MB: this doesn't take warping into account, replaced with code based on mSamplePos
//mT += (maxOut / mRate);
delete [] channelFlags;
return maxOut;
}
@ -719,14 +694,12 @@ double Mixer::MixGetCurrentTime()
void Mixer::Restart()
{
int i;
mTime = mT0;
for(i=0; i<mNumInputTracks; i++)
for(size_t i=0; i<mNumInputTracks; i++)
mSamplePos[i] = mInputTrack[i].GetTrack()->TimeToLongSamples(mT0);
for(i=0; i<mNumInputTracks; i++) {
for(size_t i=0; i<mNumInputTracks; i++) {
mQueueStart[i] = 0;
mQueueLen[i] = 0;
}
@ -734,8 +707,6 @@ void Mixer::Restart()
void Mixer::Reposition(double t)
{
int i;
mTime = t;
const bool backwards = (mT1 < mT0);
if (backwards)
@ -743,7 +714,7 @@ void Mixer::Reposition(double t)
else
mTime = std::max(mT0, (std::min(mT1, mTime)));
for(i=0; i<mNumInputTracks; i++) {
for(size_t i=0; i<mNumInputTracks; i++) {
mSamplePos[i] = mInputTrack[i].GetTrack()->TimeToLongSamples(mTime);
mQueueStart[i] = 0;
mQueueLen[i] = 0;
@ -789,22 +760,11 @@ MixerSpec::MixerSpec( const MixerSpec &mixerSpec )
void MixerSpec::Alloc()
{
mMap = new bool*[ mNumTracks ];
for( int i = 0; i < mNumTracks; i++ )
mMap[ i ] = new bool[ mMaxNumChannels ];
mMap.reinit(mNumTracks, mMaxNumChannels);
}
MixerSpec::~MixerSpec()
{
Free();
}
void MixerSpec::Free()
{
for( int i = 0; i < mNumTracks; i++ )
delete[] mMap[ i ];
delete[] mMap;
}
bool MixerSpec::SetNumChannels( unsigned newNumChannels )
@ -830,8 +790,6 @@ bool MixerSpec::SetNumChannels( unsigned newNumChannels )
MixerSpec& MixerSpec::operator=( const MixerSpec &mixerSpec )
{
Free();
mNumTracks = mixerSpec.mNumTracks;
mNumChannels = mixerSpec.mNumChannels;
mMaxNumChannels = mixerSpec.mMaxNumChannels;

View File

@ -51,10 +51,9 @@ class AUDACITY_DLL_API MixerSpec
unsigned mNumTracks, mNumChannels, mMaxNumChannels;
void Alloc();
void Free();
public:
bool **mMap;
public:
ArraysOf<bool> mMap;
MixerSpec( unsigned numTracks, unsigned maxNumChannels );
MixerSpec( const MixerSpec &mixerSpec );
@ -150,38 +149,37 @@ class AUDACITY_DLL_API Mixer {
Resample * pResample);
private:
// Input
int mNumInputTracks;
WaveTrackCache *mInputTrack;
// Input
size_t mNumInputTracks;
ArrayOf<WaveTrackCache> mInputTrack;
bool mbVariableRates;
const TimeTrack *mTimeTrack;
sampleCount *mSamplePos;
ArrayOf<sampleCount> mSamplePos;
bool mApplyTrackGains;
float *mGains;
double *mEnvValues;
Doubles mEnvValues;
double mT0; // Start time
double mT1; // Stop time (none if mT0==mT1)
double mTime; // Current time (renamed from mT to mTime for consistency with AudioIO - mT represented warped time there)
Resample **mResample;
float **mSampleQueue;
int *mQueueStart;
int *mQueueLen;
ArrayOf<std::unique_ptr<Resample>> mResample;
size_t mQueueMaxLen;
FloatBuffers mSampleQueue;
ArrayOf<int> mQueueStart;
ArrayOf<int> mQueueLen;
size_t mProcessLen;
MixerSpec *mMixerSpec;
// Output
size_t mMaxOut;
unsigned mNumChannels;
Floats mGains;
unsigned mNumBuffers;
size_t mBufferSize;
size_t mInterleavedBufferSize;
sampleFormat mFormat;
bool mInterleaved;
SampleBuffer *mBuffer;
SampleBuffer *mTemp;
float *mFloatBuffer;
ArrayOf<SampleBuffer> mBuffer, mTemp;
Floats mFloatBuffer;
double mRate;
double mSpeed;
bool mHighQuality;

View File

@ -622,7 +622,15 @@ class AUDACITY_DLL_API WaveTrack final : public Track {
// one block file).
class WaveTrackCache {
public:
explicit WaveTrackCache(const WaveTrack *pTrack = 0)
WaveTrackCache()
: mPTrack(0)
, mBufferSize(0)
, mOverlapBuffer()
, mNValidBuffers(0)
{
}
explicit WaveTrackCache(const WaveTrack *pTrack)
: mPTrack(0)
, mBufferSize(0)
, mOverlapBuffer()