Repository navigation
Conversation
The float->integer convert_to already had a volume multiplier; add the matching integer->float gain to convert_from in every ISA (Default, SSE41, AVX2, AVX512, NEON), the dispatcher, and the explicit instantiations. This work also fixed two latent bugs in the SIMD u8 convert_to paths, exposed by testing the multiplier: the gain was applied after the clamp (so a loud signal with gain could scale past the uint8 range instead of clipping to it, matching Default), and the rounding offset was the scaled SCALE instead of the constant 128.5. The u8 convert_from paths scale by (multiplier / 128) and subtract the multiplier - the old constant -1 bias was only correct for a gain of 1. RawAudio2WorkingAudio now takes the multiplier in its constructor and exposes set_multiplier(), mirroring WorkingAudio2RawAudio; it passes the atomic value into convert_from on every block. Tests: the kernel round-trip tests now run with reciprocal multiplier pairs (1.0/1.0, 0.5/2.0, 0.25/4.0) - exact in binary and in-range for the uint8 clamp - and the pipeline Raw->Working->Raw round-trip tests run with 0.5/2.0.
Use tostr_default() instead of a local snprintf buffer, and move the name construction out of a lambda in the member initializer into a private static make_name() method on the test classes.
_xmm_cvtps_epi32 / _mm256_cvtps_epi32 / _mm512_cvtps_epi32 are the rounding (CVTPS2DQ) conversions, not the truncating ones; the scalar Default kernels use C casts (truncation). With the new scale-then-clamp u8 path the final values land on k+0.5, where the rounding conversion diverges from the scalar (round(95.5)=96). Use the _cvttps_ (CVTTPS2DQ) truncating intrinsics in all nine x64 to-helpers. Also: - AVX512 u8 to: _mm512_cvtepi32_epi8 (VPMOVQB) saturates int32 lane values above 127, clamping the upper half of the uint8 range. Pack via a 128 bias into signed byte range, then add it back in byte lanes (mod 256). - SSE41 u8/s16 from: the SIMD iterations read a full 128-bit line while only consuming 4 samples, reading past the end of short buffers. Restructure to full-width iterations (16 u8 / 8 s16 samples) with the scalar tail handling the rest. - Remove the temporary DIAG_U8 test.
GCC declares the argument as char; 128 overflows (-Werror=overflow).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
convert_to(float -> integer) already had amultipliervolume control; this adds the matching gain toconvert_from(integer -> float) in every ISA — Default, x64 SSE41, AVX2, AVX512, ARM64 NEON — plus the dispatcher, the header, and the explicit instantiations:The gain scales the de-normalized sample:
native = (ext - bias) * scale * multiplier. The SIMDfrom_u8paths now scale bymultiplier / 128and subtractmultiplier(the old constant-1bias was only correct for a gain of 1).Latent u8 convert_to bugs found while testing
Testing the multiplier exposed two bugs in the SIMD
u8convert_topaths (SSE41/AVX2/AVX512/NEON) that were masked because the tests only ever used a multiplier of 1.0:[-1, 127/128]. The SIMD paths now match.SCALE(multiplier * 128) instead of the constant128.5that Default uses.For in-range inputs at any multiplier the new SIMD
convert_to_u8is bit-exact with Default (verified natively across out-of-domain inputs and multipliers up to 20x).Pipeline
RawAudio2WorkingAudio(theconvert_fromconsumer) now takes the multiplier in its constructor and exposesset_multiplier(), mirroringWorkingAudio2RawAudio; the converter lambda passes the atomic value on every block.WorkingAudio2RawAudioalready plumbed its multiplier intoconvert_toand is unchanged.Tests
TestFrom/TestToper ISA) now run with reciprocal multiplier pairs(1.0, 1.0),(0.5, 2.0),(0.25, 4.0)— exact in binary and kept in the native range so the round trip stays lossless (the pairs also keep the uint8toinput below its clamp). Test names carry the pair, e.g.u8_from_ARM64_NEON(120) [from 0.5 / to 2].0.5 / 2.0in addition to1.0 / 1.0, exercising the new constructor parameter and the atomic load path end to end.