Quick answer: Pygame sndarray.samples() returning data that’s not the int16 you expected? The mixer’s format determines the dtype; 8-bit unsigned, 16-bit signed, or 32-bit float each return different.
Code generating procedural audio writes int16 samples; the mixer is 8-bit, so the array misinterprets and produces noise.
Match Mixer Format
info = pygame.mixer.get_init()
freq, fmt, channels = info
# fmt = 16 means int16; -16 is signedBuild sample arrays in the matching dtype: int16 for fmt=-16, float32 for fmt=32, etc.
Pre-Init Format
pygame.mixer.pre_init(44100, -16, 2, 512)
pygame.mixer.init()Sets the format at startup. Consistent across the project; procedural audio code matches.
Channel Layout
2 channels = stereo. The sample array is shape (N, 2) for stereo; (N,) for mono. Reshape accordingly.
Clipping
Generating samples past int16 range wraps to noise. Clamp procedural output to the valid range before passing to mixer.
Verifying
Procedural audio plays cleanly. No noise, no clipping unless intended.
“sndarray dtype matches mixer init format. Pre-init the format your code expects.”
Standardize on int16 stereo — matches most audio file formats and mixer math without conversions.