File: MixerOptions.cpp

package info (click to toggle)
audacity 3.2.4%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 106,704 kB
  • sloc: cpp: 277,038; ansic: 73,623; lisp: 7,761; python: 3,305; sh: 2,715; perl: 821; xml: 275; makefile: 119
file content (140 lines) | stat: -rw-r--r-- 3,752 bytes parent folder | download
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;
}