-
-
Notifications
You must be signed in to change notification settings - Fork 216
SDL3 _audio module
#3657
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
base: main
Are you sure you want to change the base?
SDL3 _audio module
#3657
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,164 @@ | ||
| from collections.abc import Callable | ||
| from typing import TypeVar | ||
|
|
||
| from pygame.typing import FileLike | ||
| from typing_extensions import Buffer | ||
|
|
||
| # TODO: Support SDL3 stubchecking without failing when on SDL2 builds | ||
| # Right now this module is unconditionally skipped in mypy_allow_list.txt | ||
|
|
||
| def init() -> None: ... | ||
|
|
||
| # def quit() -> None: ... | ||
| def get_init() -> bool: ... | ||
| def get_current_driver() -> str: ... | ||
| def get_drivers() -> list[str]: ... | ||
| def get_playback_devices() -> list[AudioDevice]: ... | ||
| def get_recording_devices() -> list[AudioDevice]: ... | ||
|
|
||
| # def mix_audio(dst: Buffer, src: Buffer, format: AudioFormat, volume: float) -> None: ... | ||
| def load_wav(file: FileLike) -> tuple[AudioSpec, bytes]: ... | ||
|
|
||
| # def convert_samples( | ||
| # src_spec: AudioSpec, src_data: Buffer, dst_spec: AudioSpec | ||
| # ) -> bytes: ... | ||
|
|
||
| DEFAULT_PLAYBACK_DEVICE: AudioDevice | ||
| DEFAULT_RECORDING_DEVICE: AudioDevice | ||
|
|
||
| # T = TypeVar("T") | ||
| # stream_callback = Callable[[T, AudioStream, int, int], None] | ||
| # post_mix_callback = Callable[[T, AudioStream, Buffer], None] | ||
| # iteration_callback = Callable[[T, AudioDevice, bool], None] | ||
|
|
||
| class AudioFormat: | ||
| @property | ||
| def bitsize(self) -> int: ... | ||
| @property | ||
| def bytesize(self) -> int: ... | ||
| @property | ||
| def is_float(self) -> bool: ... | ||
| @property | ||
| def is_int(self) -> bool: ... | ||
| @property | ||
| def is_big_endian(self) -> bool: ... | ||
| @property | ||
| def is_little_endian(self) -> bool: ... | ||
| @property | ||
| def is_signed(self) -> bool: ... | ||
| @property | ||
| def is_unsigned(self) -> bool: ... | ||
| @property | ||
| def name(self) -> str: ... | ||
| @property | ||
| def silence_value(self) -> bytes: ... | ||
| def __index__(self) -> int: ... | ||
| def __repr__(self) -> str: ... | ||
|
|
||
| UNKNOWN: AudioFormat | ||
| U8: AudioFormat | ||
| S8: AudioFormat | ||
| S16LE: AudioFormat | ||
| S16BE: AudioFormat | ||
| S32LE: AudioFormat | ||
| S32BE: AudioFormat | ||
| F32LE: AudioFormat | ||
| F32BE: AudioFormat | ||
| S16: AudioFormat | ||
| S32: AudioFormat | ||
| F32: AudioFormat | ||
|
|
||
| class AudioSpec: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this could be a
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe in the first draft it was, but when I actually went to write it I wanted understandable full control over all of the runtime consequences. Like I made the fields immutable. So for the typing and implementation I don’t see an advantage to making it into a dataclass. |
||
| def __init__(self, format: AudioFormat, channels: int, frequency: int) -> None: ... | ||
| @property | ||
| def format(self) -> AudioFormat: ... | ||
| @property | ||
| def channels(self) -> int: ... | ||
| @property | ||
| def frequency(self) -> int: ... | ||
| @property | ||
| def framesize(self) -> int: ... | ||
| def __repr__(self) -> str: ... | ||
|
|
||
| class AudioDevice: | ||
| def open(self, spec: AudioSpec | None = None) -> LogicalAudioDevice: ... | ||
| # def open_stream( | ||
| # self, | ||
| # spec: AudioSpec | None, | ||
| # callback: stream_callback | None, | ||
| # userdata: T | None, | ||
| # ) -> AudioStream: ... | ||
| @property | ||
| def is_playback(self) -> bool: ... | ||
| @property | ||
| def name(self) -> str: ... | ||
| # Need something for https://wiki.libsdl.org/SDL3/SDL_GetAudioDeviceFormat | ||
| @property | ||
| def channel_map(self) -> list[int] | None: ... | ||
|
|
||
| class LogicalAudioDevice(AudioDevice): | ||
| def pause(self) -> None: ... | ||
| def resume(self) -> None: ... | ||
| @property | ||
| def paused(self) -> bool: ... | ||
| @property | ||
| def gain(self) -> float: ... | ||
| @gain.setter | ||
| def gain(self, value: float) -> None: ... | ||
| # def set_iteration_callbacks( | ||
| # self, | ||
| # start: iteration_callback | None, | ||
| # end: iteration_callback | None, | ||
| # userdata: T, | ||
| # ) -> None: ... | ||
| # def set_post_mix_callback( | ||
| # self, callback: post_mix_callback | None, userdata: T | ||
| # ) -> None: ... | ||
|
|
||
| class AudioStream: | ||
| def __init__(self, src_spec: AudioSpec, dst_spec: AudioSpec) -> None: ... | ||
| def bind(self, device: LogicalAudioDevice) -> None: ... | ||
| def unbind(self) -> None: ... | ||
| def clear(self) -> None: ... | ||
| def flush(self) -> None: ... | ||
| @property | ||
| def num_available_bytes(self) -> int: ... | ||
| @property | ||
| def num_queued_bytes(self) -> int: ... | ||
| def get_data(self, size: int) -> bytes: ... | ||
| def put_data(self, data: Buffer) -> None: ... | ||
| def pause_device(self) -> None: ... | ||
| def resume_device(self) -> None: ... | ||
| @property | ||
| def device_paused(self) -> bool: ... | ||
| @property | ||
| def device(self) -> LogicalAudioDevice | None: ... | ||
| @property | ||
| def src_spec(self) -> AudioSpec: ... | ||
| @src_spec.setter | ||
| def src_spec(self, value: AudioSpec) -> None: ... | ||
| @property | ||
| def dst_spec(self) -> AudioSpec: ... | ||
| @dst_spec.setter | ||
| def dst_spec(self, value: AudioSpec) -> None: ... | ||
| @property | ||
| def gain(self) -> float: ... | ||
| @gain.setter | ||
| def gain(self, value: float) -> None: ... | ||
| @property | ||
| def frequency_ratio(self) -> float: ... | ||
| @frequency_ratio.setter | ||
| def frequency_ratio(self, value: float) -> None: ... | ||
| # def set_input_channel_map(self, channel_map: list[int] | None) -> None: ... | ||
| # def get_input_channel_map(self) -> list[int] | None: ... | ||
| # def set_output_channel_map(self, channel_map: list[int] | None) -> None: ... | ||
| # def get_output_channel_map(self) -> list[int] | None: ... | ||
| def lock(self) -> None: ... | ||
| def unlock(self) -> None: ... | ||
| # def set_get_callback( | ||
| # self, callback: stream_callback | None, userdata: T | ||
| # ) -> None: ... | ||
| # def set_put_callback( | ||
| # self, callback: stream_callback | None, userdata: T | ||
| # ) -> None: ... | ||
| def __repr__(self) -> str: ... | ||
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.
I think implementing
__eq__would be handy too, so users could sayspec.format == U8or something like that.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.
This is handled by Python’s default identity comparison, because AudioFormats are singletons.