forked from Sneeds-Feed-and-Seed/sneedacity
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMix.h
201 lines (156 loc) · 6.19 KB
/
Mix.h
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/**********************************************************************
Sneedacity: A Digital Audio Editor
Mix.h
Dominic Mazzoni
Markus Meyer
********************************************************************//**
\class ArrayOf
\brief Memory.h template class for making an array of float, bool, etc.
\class ArraysOf
\brief memory.h template class for making an array of arrays.
*//********************************************************************/
#ifndef __SNEEDACITY_MIX__
#define __SNEEDACITY_MIX__
#include "SampleFormat.h"
#include <vector>
class Resample;
class BoundedEnvelope;
class WaveTrackFactory;
class TrackList;
class WaveTrack;
using WaveTrackConstArray = std::vector < std::shared_ptr < const WaveTrack > >;
class WaveTrackCache;
/** @brief Mixes together all input tracks, applying any envelopes, amplitude
* gain, panning, and real-time effects in the process.
*
* Takes one or more tracks as input; of all the WaveTrack s that are selected,
* it mixes them together, applying any envelopes, amplitude gain, panning, and
* real-time effects in the process. The resulting pair of tracks (stereo) are
* "rendered" and have no effects, gain, panning, or envelopes. Other sorts of
* tracks are ignored.
* If the start and end times passed are the same this is taken as meaning
* no explicit time range to process, and the whole occupied length of the
* input tracks is processed.
*/
void SNEEDACITY_DLL_API MixAndRender(TrackList * tracks, WaveTrackFactory *factory,
double rate, sampleFormat format,
double startTime, double endTime,
std::shared_ptr<WaveTrack> &uLeft,
std::shared_ptr<WaveTrack> &uRight);
void MixBuffers(unsigned numChannels, int *channelFlags, float *gains,
samplePtr src,
samplePtr *dests, int len, bool interleaved);
class SNEEDACITY_DLL_API MixerSpec
{
unsigned mNumTracks, mNumChannels, mMaxNumChannels;
void Alloc();
public:
ArraysOf<bool> mMap;
MixerSpec( unsigned numTracks, unsigned maxNumChannels );
MixerSpec( const MixerSpec &mixerSpec );
virtual ~MixerSpec();
bool SetNumChannels( unsigned numChannels );
unsigned GetNumChannels() { return mNumChannels; }
unsigned GetMaxNumChannels() { return mMaxNumChannels; }
unsigned GetNumTracks() { return mNumTracks; }
MixerSpec& operator=( const MixerSpec &mixerSpec );
};
class SNEEDACITY_DLL_API Mixer {
public:
// An argument to Mixer's constructor
class SNEEDACITY_DLL_API WarpOptions
{
public:
//! Construct with warp from the TimeTrack if there is one
explicit WarpOptions(const TrackList &list);
//! Construct with an explicit warp
explicit WarpOptions(const BoundedEnvelope *e);
//! Construct with no time warp
WarpOptions(double min, double max);
private:
friend class Mixer;
const BoundedEnvelope *envelope = nullptr;
double minSpeed, maxSpeed;
};
//
// Constructor / Destructor
//
Mixer(const WaveTrackConstArray &inputTracks, bool mayThrow,
const WarpOptions &warpOptions,
double startTime, double stopTime,
unsigned numOutChannels, size_t outBufferSize, bool outInterleaved,
double outRate, sampleFormat outFormat,
bool highQuality = true, MixerSpec *mixerSpec = nullptr,
bool applytTrackGains = true);
virtual ~ Mixer();
//
// Processing
//
/// Process a maximum of 'maxSamples' samples and put them into
/// a buffer which can be retrieved by calling GetBuffer().
/// Returns number of output samples, or 0, if there are no
/// more samples that must be processed.
size_t Process(size_t maxSamples);
/// Restart processing at beginning of buffer next time
/// Process() is called.
void Restart();
/// Reposition processing to absolute time next time
/// Process() is called.
void Reposition(double t, bool bSkipping = false);
// Used in scrubbing.
void SetTimesAndSpeed(double t0, double t1, double speed);
void SetSpeedForPlayAtSpeed(double speed);
void SetSpeedForKeyboardScrubbing(double speed, double startTime);
/// Current time in seconds (unwarped, i.e. always between startTime and stopTime)
/// This value is not accurate, it's useful for progress bars and indicators, but nothing else.
double MixGetCurrentTime();
/// Retrieve the main buffer or the interleaved buffer
samplePtr GetBuffer();
/// Retrieve one of the non-interleaved buffers
samplePtr GetBuffer(int channel);
private:
void Clear();
size_t MixSameRate(int *channelFlags, WaveTrackCache &cache,
sampleCount *pos);
size_t MixVariableRates(int *channelFlags, WaveTrackCache &cache,
sampleCount *pos, float *queue,
int *queueStart, int *queueLen,
Resample * pResample);
void MakeResamplers();
private:
// Input
const size_t mNumInputTracks;
ArrayOf<WaveTrackCache> mInputTrack;
bool mbVariableRates;
const BoundedEnvelope *mEnvelope;
ArrayOf<sampleCount> mSamplePos;
const bool mApplyTrackGains;
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)
ArrayOf<std::unique_ptr<Resample>> mResample;
const size_t mQueueMaxLen;
FloatBuffers mSampleQueue;
ArrayOf<int> mQueueStart;
ArrayOf<int> mQueueLen;
size_t mProcessLen;
MixerSpec *mMixerSpec;
// Output
size_t mMaxOut;
const unsigned mNumChannels;
Floats mGains;
unsigned mNumBuffers;
size_t mBufferSize;
size_t mInterleavedBufferSize;
const sampleFormat mFormat;
bool mInterleaved;
ArrayOf<SampleBuffer> mBuffer, mTemp;
Floats mFloatBuffer;
const double mRate;
double mSpeed;
bool mHighQuality;
std::vector<double> mMinFactor, mMaxFactor;
const bool mMayThrow;
};
#endif