67{
68 wxASSERT(len > 0);
71 if (s0 >= numSamples)
72
73 return false;
74
75
76
77
78 const auto s1 = std::clamp(where[len], 1 + where[len - 1], numSamples);
81
82 decltype(len) pixel = 0;
83
84 auto srcX = s0;
85 decltype(srcX) nextSrcX = 0;
86 int lastRmsDenom = 0;
87 int lastDivisor = 0;
88 auto whereNow =
std::min(s1 - 1, where[0]);
89 decltype(whereNow) whereNext = 0;
90
91
93 unsigned nBlocks = blocks.size();
94 const unsigned int block0 = sequence.
FindBlock(s0);
95 for (unsigned int b = block0; b < nBlocks; ++b) {
96 if (b > block0)
97 srcX = nextSrcX;
98 if (srcX >= s1)
99 break;
100
101
102
103 const SeqBlock &seqBlock = blocks[b];
104 const auto start = seqBlock.
start;
105 nextSrcX =
std::min(s1, start + seqBlock.
sb->GetSampleCount());
106
107
108
109
110
111
112 decltype(len) nextPixel;
113 if (nextSrcX >= s1)
114
115 nextPixel = len;
116 else {
117 nextPixel = pixel;
118
119
120 while (nextPixel < len &&
121 (whereNext =
std::min(s1 - 1, where[nextPixel])) < nextSrcX)
122 ++nextPixel;
123 }
124 if (nextPixel == pixel)
125
126
127
128
129
130
131
132 continue;
133 if (nextPixel == len)
134 whereNext = s1;
135
136
137 const double samplesPerPixel =
138 (whereNext - whereNow).as_double() / (nextPixel - pixel);
139 const int divisor =
140 (samplesPerPixel >= 65536) ? 65536
141 : (samplesPerPixel >= 256) ? 256
142 : 1;
143
144 int blockStatus = b;
145
146
147
148 const size_t startPosition =
149
150 std::max(
sampleCount(0), (srcX - start) / divisor).as_size_t();
151 const size_t inclusiveEndPosition =
152
154 (nextSrcX - 1 - start) / divisor).as_size_t();
155 const auto num = 1 + inclusiveEndPosition - startPosition;
156 if (num <= 0) {
157
158 wxASSERT(false);
159
160 while (pixel < nextPixel) {
161 min[pixel] = max[pixel] = rms[pixel] = 0;
162 bl[pixel] = blockStatus;
163 ++pixel;
164 }
165 continue;
166 }
167
168
169 switch (divisor) {
170 default:
171 case 1:
172
173
176 break;
177 case 256:
178
179
180
181 seqBlock.
sb->GetSummary256(temp.get(), startPosition, num);
182 break;
183 case 65536:
184
185
186
187 seqBlock.
sb->GetSummary64k(temp.get(), startPosition, num);
188 break;
189 }
190
191 auto filePosition = startPosition;
192
193
194
195 if (b > block0 && pixel > 0) {
196
197 auto midPosition = ((whereNow - start) / divisor).as_size_t();
198 int diff(midPosition - filePosition);
199 if (diff > 0) {
200 MinMaxSumsq
values(temp.get(), diff, divisor);
201 const int lastPixel = pixel - 1;
202 float &lastMin =
min[lastPixel];
204 float &lastMax = max[lastPixel];
205 lastMax = std::max(lastMax,
values.max);
206 float &lastRms = rms[lastPixel];
207 int lastNumSamples = lastRmsDenom * lastDivisor;
209 (lastRms * lastRms * lastNumSamples +
values.sumsq * divisor) /
210 (lastNumSamples + diff * divisor)
211 );
212
213 filePosition = midPosition;
214 }
215 }
216
217
218 int rmsDenom = 0;
219 for (; filePosition <= inclusiveEndPosition;) {
220
221
222
223
224 auto pixelX = pixel + 1;
225 decltype(filePosition) positionX = 0;
226 while (pixelX < nextPixel &&
227 filePosition ==
228 (positionX = (
229
230 (
std::min(s1 - 1, where[pixelX]) - start) / divisor).as_size_t() )
231 )
232 ++pixelX;
233 if (pixelX >= nextPixel)
234 positionX = 1 + inclusiveEndPosition;
235
236
237 rmsDenom = (positionX - filePosition);
238 wxASSERT(rmsDenom > 0);
239 const float *const pv =
240 temp.get() + (filePosition - startPosition) * (divisor == 1 ? 1 : 3);
241 MinMaxSumsq
values(pv, std::max(0, rmsDenom), divisor);
242
243
245 std::fill(&max[pixel], &max[pixelX],
values.max);
246 std::fill(&bl[pixel], &bl[pixelX], blockStatus);
247 std::fill(&rms[pixel], &rms[pixelX], (
float)
sqrt(
values.sumsq / rmsDenom));
248
249 pixel = pixelX;
250 filePosition = positionX;
251 }
252
253 wxASSERT(pixel == nextPixel);
254 whereNow = whereNext;
255 pixel = nextPixel;
256 lastDivisor = divisor;
257 lastRmsDenom = rmsDenom;
258 }
259
260 wxASSERT(pixel == len);
261
262 return true;
263}
Data structure containing pointer to a sample block and a start time. Element of a BlockArray.
sampleCount start
the sample in the global wavetrack that this block starts at.
size_t GetMaxBlockSize() const
sampleCount GetNumSamples() const
static bool Read(samplePtr buffer, sampleFormat format, const SeqBlock &b, size_t blockRelativeStart, size_t len, bool mayThrow)
int FindBlock(sampleCount pos) const
BlockArray & GetBlockArray()
Positions or offsets within audio files need a wide type.
__finl float_x4 __vecc sqrt(const float_x4 &a)