- SoundBuffer.gain(factor): new DSP method for amplitude scaling before
mixing (0.5 = half volume, 2.0 = double, clamped to int16 range)
- Fix sfxr square/saw waveform artifacts: phase now wraps at period
boundary instead of growing unbounded; noise buffer refreshes per period
- Fix PySound construction from SoundBuffer on SDL2 backend: use
loadFromSamples() directly instead of copy-assign (deleted on SDL2)
- Add Image::create(w, h, pixels) overload to HeadlessTypes and
SDL2Types for pixel data initialization
- Waveform test suite (62 lines)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace module-level audio functions with proper OOP API:
- mcrfpy.Sound: Wraps sf::SoundBuffer + sf::Sound for short effects
- mcrfpy.Music: Wraps sf::Music for streaming long tracks
- Both support: volume, loop, playing, duration, play/pause/stop
- Music adds position property for seeking
Add mcrfpy.keyboard singleton for real-time modifier state:
- shift, ctrl, alt, system properties (bool, read-only)
- Queries sf::Keyboard::isKeyPressed() directly
Add mcrfpy.__version__ = "1.0.0" for version identity
Remove old audio API entirely (no deprecation - unused in codebase):
- createSoundBuffer, loadMusic, playSound
- setMusicVolume, getMusicVolume, setSoundVolume, getSoundVolume
closes#66, closes#160, closes#164🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>