FastLED 3.10.6
Loading...
Searching...
No Matches

◆ run()

Result autoresearch::mp3_check::run ( )
inline

Definition at line 146 of file AutoResearchMp3.h.

146 {
147 Result r;
148 fl::memset(&r, 0, sizeof(r));
149 r.success = true;
150 r.first_failure = nullptr;
151 r.scratch_bytes = (fl::u32)sizeof(fl::third_party::mp3dec_scratch_t);
152 r.shared_decoder_matched = true;
153 r.combined_fnv1a = 2166136261u;
154
155 // The decoder state and scratch arena are far too large for the stack on a
156 // microcontroller -- roughly 11 KB and 8 KB -- so they go on the heap, once.
161 // make_unique<T[]> yields unique_ptr<T[]>, released with delete[].
163 if (!dec || !scratch || !pcm) {
164 r.success = false;
165 r.first_failure = "allocation";
166 return r;
167 }
168
169 const fl::u32 started = (fl::u32)micros();
170 fl::u32 audio_us = 0;
171
172 // Pass 1: a fresh decoder per stream, which is how the host fixture was
173 // produced. This is the bit-exactness check.
174 for (fl::u32 i = 0; i < mp3_fixture::kStreamCount; ++i) {
176 fl::third_party::mp3dec_init(dec.get());
177 const Decoded got = decodeStream(dec.get(), scratch.get(), pcm.get(), s);
178 ++r.streams_run;
179 r.samples_decoded += got.samples;
180 r.frames_decoded += got.frames;
181 r.combined_fnv1a = fnv1a_mix(r.combined_fnv1a, got.fnv1a);
182 if (s.hz > 0u && s.channels > 0u) {
183 const fl::u32 per_channel = got.samples / s.channels;
184 audio_us += (fl::u32)(((fl::u64)per_channel * 1000000ull) / s.hz);
185 }
186 if (got.fnv1a != s.fnv1a || got.samples != s.samples ||
187 got.frames != s.frames || got.hz != s.hz ||
188 got.channels != s.channels || got.layer != s.layer) {
189 recordFailure(r, s.name, s.fnv1a, got.fnv1a, s.samples,
190 got.samples);
191 }
192 }
193
194 r.decode_micros = (fl::u32)micros() - started;
195 r.audio_micros = audio_us;
196 const fl::u32 verify_started = (fl::u32)micros();
197
198 // Pass 2: one decoder driven across every stream in turn, without
199 // re-initialising between them. Layer I/II scale info and Layer III's
200 // main-data window share arena storage (FastLED#4116) on the grounds that a
201 // frame is one layer or the other and never both. If that is wrong -- or if
202 // it is right on x86-64 and wrong here, where the struct is packed
203 // differently -- the second stream decodes differently than it did alone.
204 fl::third_party::mp3dec_init(dec.get());
205 for (fl::u32 i = 0; i < mp3_fixture::kStreamCount; ++i) {
206 const mp3_fixture::Stream& s = mp3_fixture::kStreams[i];
207 const Decoded got = decodeStream(dec.get(), scratch.get(), pcm.get(), s);
208 if (got.fnv1a != s.fnv1a || got.samples != s.samples ||
209 got.hz != s.hz || got.channels != s.channels ||
210 got.layer != s.layer) {
211 r.shared_decoder_matched = false;
212 if (r.first_failure == nullptr) {
213 r.first_failure = s.name;
214 r.expected_fnv1a = s.fnv1a;
215 r.actual_fnv1a = got.fnv1a;
216 r.expected_samples = s.samples;
217 r.actual_samples = got.samples;
218 }
219 }
220 }
221
222 r.verify_micros = (fl::u32)micros() - verify_started;
225 return r;
226}
pointer get() const FL_NO_EXCEPT
Definition unique_ptr.h:97
void recordFailure(Result &r, const char *name, fl::u32 expected_hash, fl::u32 actual_hash, fl::u32 expected_samples, fl::u32 actual_samples)
fl::u32 fnv1a_mix(fl::u32 hash, fl::u32 value)
Fold one stream's checksum into the run-wide one, so a single reported value covers every stream in o...
Decoded decodeStream(fl::third_party::mp3dec_t *dec, fl::third_party::mp3dec_scratch_t *scratch, fl::i16 *pcm, const mp3_fixture::Stream &stream)
Decode one stream.
const dec_t dec
Definition ios.cpp.hpp:13
fl::enable_if<!fl::is_array< T >::value, unique_ptr< T > >::type make_unique(Args &&... args) FL_NO_EXCEPT
Definition unique_ptr.h:261
fl::u32 micros()
Universal microsecond timer - returns microseconds since system startup.
void * memset(void *s, int c, size_t n) FL_NO_EXCEPT

References autoresearch::mp3_check::Result::actual_fnv1a, autoresearch::mp3_check::Result::actual_samples, autoresearch::mp3_check::Result::audio_micros, autoresearch::mp3_check::Decoded::channels, autoresearch::mp3_fixture::Stream::channels, autoresearch::mp3_check::Result::combined_fnv1a, autoresearch::mp3_check::Result::decode_micros, decodeStream(), autoresearch::mp3_check::Result::expected_fnv1a, autoresearch::mp3_check::Result::expected_samples, autoresearch::mp3_check::Result::first_failure, autoresearch::mp3_check::Decoded::fnv1a, autoresearch::mp3_fixture::Stream::fnv1a, fnv1a_mix(), autoresearch::mp3_check::Decoded::frames, autoresearch::mp3_fixture::Stream::frames, autoresearch::mp3_check::Result::frames_decoded, fl::unique_ptr< T, Deleter >::get(), autoresearch::mp3_check::Decoded::hz, autoresearch::mp3_fixture::Stream::hz, autoresearch::mp3_fixture::kStreamCount, autoresearch::mp3_fixture::kStreams, autoresearch::mp3_check::Decoded::layer, autoresearch::mp3_fixture::Stream::layer, fl::make_unique(), fl::memset(), autoresearch::mp3_fixture::Stream::name, recordFailure(), autoresearch::mp3_check::Decoded::samples, autoresearch::mp3_fixture::Stream::samples, autoresearch::mp3_check::Result::samples_decoded, autoresearch::mp3_check::Result::scratch_bytes, autoresearch::mp3_check::Result::shared_decoder_matched, autoresearch::mp3_check::Result::streams_failed, autoresearch::mp3_check::Result::streams_run, autoresearch::mp3_check::Result::success, and autoresearch::mp3_check::Result::verify_micros.

+ Here is the call graph for this function: