- 
 
 - 
  Notifications
 
You must be signed in to change notification settings  - Fork 210
 
Support devicename=None in _sdl2.AudioDevice #3617
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support devicename=None in _sdl2.AudioDevice #3617
Conversation
 
📝 WalkthroughWalkthroughAllow  Changes
 Sequence Diagram(s)sequenceDiagram
 participant Py as Python caller
 participant C as Cython wrapper
 participant SDL as SDL library
 Py->>C: open_audio(devicename)
 alt devicename is None
 C->>C: devicename_ptr = NULL
 else devicename provided
 C->>C: encode devicename -> utf8_ptr
 C->>C: devicename_ptr = utf8_ptr
 end
 C->>SDL: SDL_OpenAudioDevice(devicename_ptr, ...)
 alt success
 SDL-->>C: device_id
 C-->>Py: device object / id
 else failure
 SDL-->>C: NULL / error
 C-->>Py: raise error
 end
 Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Pre-merge checks and finishing touches❌ Failed checks (1 warning)
 ✅ Passed checks (2 passed)
 ✨ Finishing touches
 🧪 Generate unit tests (beta)
 📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (2)
 🔇 Additional comments (3)
 Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment   | 
 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src_c/cython/pygame/_sdl2/audio.pyx (1)
145-160: Consider refactoring to reduce duplication.The
SDL_OpenAudioDevicecall is duplicated in both branches with only the first parameter differing. You could reduce duplication with:+ cdef bytes device_name_bytes + cdef const char* device_name_ptr if self._devicename is None: - self._deviceid = SDL_OpenAudioDevice( - NULL, - self._iscapture, - &self.desired, - &self.obtained, - allowed_changes - ) + device_name_ptr = NULL else: - self._deviceid = SDL_OpenAudioDevice( - self._devicename.encode("utf-8"), - self._iscapture, - &self.desired, - &self.obtained, - allowed_changes - ) + device_name_bytes = self._devicename.encode("utf-8") + device_name_ptr = device_name_bytes + + self._deviceid = SDL_OpenAudioDevice( + device_name_ptr, + self._iscapture, + &self.desired, + &self.obtained, + allowed_changes + )Note: Keeping
device_name_bytesalive ensures the pointer remains valid during the C call.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src_c/cython/pygame/_sdl2/audio.pyx(2 hunks)
🔇 Additional comments (2)
src_c/cython/pygame/_sdl2/audio.pyx (2)
134-135: LGTM! Type validation correctly supports None.The type check properly allows
Noneand validates that non-Nonevalues are strings. The error message accurately reflects the accepted types.
145-160: Correctly implements None support for default device.The branching logic properly passes
NULLtoSDL_OpenAudioDevicewhendevicenameisNone, which selects the default device per SDL2 API. UTF-8 encoding for non-Nonedevice names is appropriate.
e42b76c to
 3dd631d  
 Compare
 
 There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello, thanks for contributing to pygame-ce! 🥳
The code changes are looking good, but the type stubs (at buildconfig/stubs/pygame/_sdl2/audio.pyi) are still incorrect, could you fix that too in this PR?
The devicename arg of __init__ and devicename property of the class should both be typed as Optional[str]
The docstring already claimed that this was supported, but it didn't work.
3dd631d to
 e0b4055  
 Compare
 
 There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks again for the PR! 😎
@rhendric Can you provide some details about your use of the _sdl2.audio API? I'm curious. I was unaware anyone used it, besides from the list device names function.
I'm only using it for the async audio API. I'm playing with generating music dynamically in real time, so I don't have pre-recorded audio files to play, and so getting a callback invoked when SDL needs audio data is much more straightforward than racing to proactively queue up Sounds through the mixer API.
I should probably also mention that I'm in the very early stages of experimenting with this, and while my first demo script showed promise, in the context of a larger application I'm currently struggling with some skipping issues that might force me to switch to synchronous after all (though there seems to be a different bug in the mixer API that is getting in the way of queuing dynamic Sounds repeatedly). So don't move any mountains based solely on my use case just yet.
@rhendric You might be interested in what I've been working on for SDL3 audio support then, where it will hopefully not be hidden away in a private undocumented module. #3581
though there seems to be a different bug in the mixer API that is getting in the way of queuing dynamic Sounds repeatedly
Are you running into the default limit of 8 sounds playing at once? That can be raised.
SDL3 audio support
Looks good! The open_stream function in particular would be a match for my use case, I think, provided that something like the overhead of waiting for the GIL on every callback isn't the source of my current woes.
Are you running into the default limit of 8 sounds playing at once?
No, I think I'm running into #531. There's a race condition between the main thread rapidly queuing sound data and the SDL thread moving sounds from the queue field to the sound field for the channel. The root issue seems to be that endsound_callback in mixer.c tests whether queue is NULL before locking on anything. I have a patch that I'm in the process of stress testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Tested it out using examples/audiocapture.
The docstring already claimed that this was supported, but it didn't work.