1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
/**********************************************************************
Audacity: A Digital Audio Editor
@file MixerOptions.cpp
Dominic Mazzoni
Markus Meyer
Vaughan Johnson
Paul Licameli split from Mix.cpp
**********************************************************************/
#include "MixerOptions.h"
#include "Envelope.h"
#include "SampleTrack.h"
MixerOptions::Warp::Warp(const TrackList &list)
: envelope(DefaultWarp::Call(list)), minSpeed(0.0), maxSpeed(0.0)
{
}
MixerOptions::Warp::Warp(const BoundedEnvelope *e)
: envelope(e), minSpeed(0.0), maxSpeed(0.0)
{}
MixerOptions::Warp::Warp(double min, double max, double initial)
: minSpeed{ std::max(0.0, std::min(min, max)) }
, maxSpeed{ std::max(0.0, std::max(min, max)) }
, initialSpeed{initial}
{
assert(min >= 0);
assert(max >= 0);
assert(min <= max);
}
MixerOptions::ResampleParameters::ResampleParameters(bool highQuality,
const SampleTrack &leader, double rate, const Warp &options
) : mHighQuality{ highQuality }
{
auto range = TrackList::Channels<const SampleTrack>(&leader);
auto size = range.size();
mMinFactor.reserve(size);
mMaxFactor.reserve(size);
for (auto pTrack : range) {
double factor = (rate / pTrack->GetRate());
if (const auto envelope = options.envelope) {
// variable rate resampling
mVariableRates = true;
mMinFactor.push_back(factor / envelope->GetRangeUpper());
mMaxFactor.push_back(factor / envelope->GetRangeLower());
}
else if (options.minSpeed > 0.0 && options.maxSpeed > 0.0) {
// variable rate resampling
mVariableRates = true;
mMinFactor.push_back(factor / options.maxSpeed);
mMaxFactor.push_back(factor / options.minSpeed);
}
else {
// constant rate resampling
mVariableRates = false;
mMinFactor.push_back(factor);
mMaxFactor.push_back(factor);
}
}
}
MixerOptions::Downmix::Downmix(unsigned numTracks, unsigned maxNumChannels)
{
mNumTracks = mNumChannels = numTracks;
mMaxNumChannels = maxNumChannels;
if( mNumChannels > mMaxNumChannels )
mNumChannels = mMaxNumChannels;
Alloc();
for( unsigned int i = 0; i < mNumTracks; i++ )
for( unsigned int j = 0; j < mNumChannels; j++ )
mMap[ i ][ j ] = ( i == j );
}
MixerOptions::Downmix::Downmix(const Downmix &mixerSpec)
{
mNumTracks = mixerSpec.mNumTracks;
mMaxNumChannels = mixerSpec.mMaxNumChannels;
mNumChannels = mixerSpec.mNumChannels;
Alloc();
for( unsigned int i = 0; i < mNumTracks; i++ )
for( unsigned int j = 0; j < mNumChannels; j++ )
mMap[ i ][ j ] = mixerSpec.mMap[ i ][ j ];
}
void MixerOptions::Downmix::Alloc()
{
mMap.reinit(mNumTracks, mMaxNumChannels);
}
MixerOptions::Downmix::~Downmix()
{
}
bool MixerOptions::Downmix::SetNumChannels(unsigned newNumChannels)
{
if( mNumChannels == newNumChannels )
return true;
if( newNumChannels > mMaxNumChannels )
return false;
for( unsigned int i = 0; i < mNumTracks; i++ )
{
for( unsigned int j = newNumChannels; j < mNumChannels; j++ )
mMap[ i ][ j ] = false;
for( unsigned int j = mNumChannels; j < newNumChannels; j++ )
mMap[ i ][ j ] = false;
}
mNumChannels = newNumChannels;
return true;
}
auto MixerOptions::Downmix::operator=(const Downmix &mixerSpec) -> Downmix &
{
mNumTracks = mixerSpec.mNumTracks;
mNumChannels = mixerSpec.mNumChannels;
mMaxNumChannels = mixerSpec.mMaxNumChannels;
Alloc();
for( unsigned int i = 0; i < mNumTracks; i++ )
for( unsigned int j = 0; j < mNumChannels; j++ )
mMap[ i ][ j ] = mixerSpec.mMap[ i ][ j ];
return *this;
}
|