or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

audio.mdevents-input.mdfile-io.mdfonts-text.mdgraphics-rendering.mdimage-processing.mdindex.mdjoystick-input.mdsprites-animation.mdsystem-utils.mdtimer.mdwindow-display.md

audio.mddocs/

0

# Audio System

1

2

Comprehensive audio playback, recording, and mixing capabilities through SDL2 audio and SDL2_mixer integration. PySDL2 provides both low-level audio device control and high-level audio mixing functions.

3

4

## Capabilities

5

6

### Core Audio Device Management

7

8

Low-level audio device functions for playback and recording.

9

10

```python { .api }

11

def SDL_GetNumAudioDevices(iscapture: int) -> int:

12

"""

13

Get number of available audio devices.

14

15

Parameters:

16

- iscapture: 0 for playback devices, 1 for recording devices

17

18

Returns:

19

Number of available devices

20

"""

21

22

def SDL_GetAudioDeviceName(index: int, iscapture: int) -> bytes:

23

"""

24

Get name of audio device.

25

26

Parameters:

27

- index: device index

28

- iscapture: 0 for playback, 1 for recording

29

30

Returns:

31

Device name as bytes

32

"""

33

34

def SDL_OpenAudioDevice(device: bytes, iscapture: int, desired: SDL_AudioSpec,

35

obtained: SDL_AudioSpec, allowed_changes: int) -> int:

36

"""

37

Open audio device for playback or recording.

38

39

Parameters:

40

- device: device name (None for default)

41

- iscapture: 0 for playback, 1 for recording

42

- desired: desired audio specification

43

- obtained: actual audio specification (may differ from desired)

44

- allowed_changes: allowed changes to audio spec

45

46

Returns:

47

Audio device ID (>= 2) on success, 0 on failure

48

"""

49

50

def SDL_CloseAudioDevice(dev: int) -> None:

51

"""Close audio device."""

52

53

def SDL_PauseAudioDevice(dev: int, pause_on: int) -> None:

54

"""Pause or unpause audio device."""

55

56

def SDL_GetAudioDeviceStatus(dev: int) -> int:

57

"""Get audio device status."""

58

```

59

60

### Audio Specification and Format

61

62

Audio format constants and specification structure.

63

64

```python { .api }

65

# Audio format constants

66

SDL_AUDIO_MASK_BITSIZE: int = 0xFF

67

SDL_AUDIO_MASK_DATATYPE: int = (1 << 8)

68

SDL_AUDIO_MASK_ENDIAN: int = (1 << 12)

69

SDL_AUDIO_MASK_SIGNED: int = (1 << 15)

70

71

# Specific audio formats

72

AUDIO_U8: int = 0x0008 # Unsigned 8-bit

73

AUDIO_S8: int = 0x8008 # Signed 8-bit

74

AUDIO_U16LSB: int = 0x0010 # Unsigned 16-bit little-endian

75

AUDIO_S16LSB: int = 0x8010 # Signed 16-bit little-endian

76

AUDIO_U16MSB: int = 0x1010 # Unsigned 16-bit big-endian

77

AUDIO_S16MSB: int = 0x9010 # Signed 16-bit big-endian

78

AUDIO_U16: int = AUDIO_U16LSB

79

AUDIO_S16: int = AUDIO_S16LSB

80

AUDIO_S32LSB: int = 0x8020 # Signed 32-bit little-endian

81

AUDIO_S32MSB: int = 0x9020 # Signed 32-bit big-endian

82

AUDIO_S32: int = AUDIO_S32LSB

83

AUDIO_F32LSB: int = 0x8120 # 32-bit floating point little-endian

84

AUDIO_F32MSB: int = 0x9120 # 32-bit floating point big-endian

85

AUDIO_F32: int = AUDIO_F32LSB

86

87

class SDL_AudioSpec:

88

"""Audio specification structure."""

89

freq: int # Sample rate (samples per second)

90

format: int # Audio format (AUDIO_S16, etc.)

91

channels: int # Number of channels (1=mono, 2=stereo)

92

silence: int # Silence value for audio format

93

samples: int # Audio buffer size in samples (power of 2)

94

padding: int # Padding

95

size: int # Audio buffer size in bytes

96

callback: ctypes.CFUNCTYPE # Audio callback function

97

userdata: ctypes.c_void_p # User data for callback

98

```

99

100

### Audio Conversion

101

102

Functions for converting between audio formats.

103

104

```python { .api }

105

def SDL_BuildAudioCVT(cvt: SDL_AudioCVT, src_format: int, src_channels: int, src_rate: int,

106

dst_format: int, dst_channels: int, dst_rate: int) -> int:

107

"""Build audio conversion structure."""

108

109

def SDL_ConvertAudio(cvt: SDL_AudioCVT) -> int:

110

"""Convert audio data using conversion structure."""

111

112

class SDL_AudioCVT:

113

"""Audio conversion structure."""

114

needed: int # Set to 1 if conversion needed

115

src_format: int # Source audio format

116

dst_format: int # Destination audio format

117

rate_incr: float # Rate conversion increment

118

buf: ctypes.POINTER(ctypes.c_uint8) # Audio buffer

119

len: int # Original audio buffer length

120

len_cvt: int # Converted audio buffer length

121

len_mult: int # Buffer length multiplier

122

len_ratio: float # Length ratio

123

```

124

125

### SDL2_mixer Integration

126

127

High-level audio mixing functions through SDL2_mixer.

128

129

```python { .api }

130

def Mix_OpenAudio(frequency: int, format: int, channels: int, chunksize: int) -> int:

131

"""

132

Initialize audio mixer.

133

134

Parameters:

135

- frequency: sample rate (22050, 44100, etc.)

136

- format: audio format (MIX_DEFAULT_FORMAT recommended)

137

- channels: number of output channels (1=mono, 2=stereo)

138

- chunksize: audio buffer size in samples

139

140

Returns:

141

0 on success, -1 on failure

142

"""

143

144

def Mix_CloseAudio() -> None:

145

"""Close audio mixer."""

146

147

def Mix_QuerySpec(frequency: ctypes.POINTER(ctypes.c_int), format: ctypes.POINTER(ctypes.c_uint16),

148

channels: ctypes.POINTER(ctypes.c_int)) -> int:

149

"""Query mixer audio format."""

150

151

def Mix_AllocateChannels(numchans: int) -> int:

152

"""Set number of mixing channels."""

153

```

154

155

### Sound Loading and Playback

156

157

Functions for loading and playing sound effects.

158

159

```python { .api }

160

def Mix_LoadWAV(file: bytes) -> Mix_Chunk:

161

"""

162

Load WAV audio file.

163

164

Parameters:

165

- file: path to WAV file as bytes

166

167

Returns:

168

Mix_Chunk object or None on failure

169

"""

170

171

def Mix_LoadWAV_RW(src: SDL_RWops, freesrc: int) -> Mix_Chunk:

172

"""Load WAV from SDL_RWops."""

173

174

def Mix_FreeChunk(chunk: Mix_Chunk) -> None:

175

"""Free audio chunk."""

176

177

def Mix_PlayChannel(channel: int, chunk: Mix_Chunk, loops: int) -> int:

178

"""

179

Play audio chunk on channel.

180

181

Parameters:

182

- channel: channel to play on (-1 for first available)

183

- chunk: audio chunk to play

184

- loops: number of loops (-1 for infinite)

185

186

Returns:

187

Channel number playing on, -1 on error

188

"""

189

190

def Mix_PlayChannelTimed(channel: int, chunk: Mix_Chunk, loops: int, ticks: int) -> int:

191

"""Play audio chunk with time limit."""

192

193

def Mix_Volume(channel: int, volume: int) -> int:

194

"""

195

Set channel volume.

196

197

Parameters:

198

- channel: channel number (-1 for all channels)

199

- volume: volume level (0-128)

200

201

Returns:

202

Previous volume level

203

"""

204

205

def Mix_Pause(channel: int) -> None:

206

"""Pause channel."""

207

208

def Mix_Resume(channel: int) -> None:

209

"""Resume channel."""

210

211

def Mix_HaltChannel(channel: int) -> int:

212

"""Stop playing on channel."""

213

214

def Mix_Playing(channel: int) -> int:

215

"""Check if channel is playing."""

216

217

def Mix_Paused(channel: int) -> int:

218

"""Check if channel is paused."""

219

```

220

221

### Music Loading and Playback

222

223

Functions for loading and playing background music.

224

225

```python { .api }

226

def Mix_LoadMUS(file: bytes) -> Mix_Music:

227

"""

228

Load music file.

229

230

Parameters:

231

- file: path to music file as bytes

232

233

Returns:

234

Mix_Music object or None on failure

235

"""

236

237

def Mix_LoadMUS_RW(src: SDL_RWops, freesrc: int) -> Mix_Music:

238

"""Load music from SDL_RWops."""

239

240

def Mix_FreeMusic(music: Mix_Music) -> None:

241

"""Free music."""

242

243

def Mix_PlayMusic(music: Mix_Music, loops: int) -> int:

244

"""

245

Play music.

246

247

Parameters:

248

- music: music to play

249

- loops: number of loops (-1 for infinite)

250

251

Returns:

252

0 on success, -1 on error

253

"""

254

255

def Mix_FadeInMusic(music: Mix_Music, loops: int, ms: int) -> int:

256

"""Play music with fade-in effect."""

257

258

def Mix_VolumeMusic(volume: int) -> int:

259

"""

260

Set music volume.

261

262

Parameters:

263

- volume: volume level (0-128)

264

265

Returns:

266

Previous volume level

267

"""

268

269

def Mix_PauseMusic() -> None:

270

"""Pause music."""

271

272

def Mix_ResumeMusic() -> None:

273

"""Resume music."""

274

275

def Mix_HaltMusic() -> int:

276

"""Stop music."""

277

278

def Mix_FadeOutMusic(ms: int) -> int:

279

"""Fade out music over time."""

280

281

def Mix_PlayingMusic() -> int:

282

"""Check if music is playing."""

283

284

def Mix_PausedMusic() -> int:

285

"""Check if music is paused."""

286

287

def Mix_GetMusicType(music: Mix_Music) -> int:

288

"""Get music type."""

289

```

290

291

### Mixer Constants and Types

292

293

Constants and types for SDL2_mixer.

294

295

```python { .api }

296

# Mixer format constants

297

MIX_DEFAULT_FREQUENCY: int = 22050

298

MIX_DEFAULT_FORMAT: int = AUDIO_S16LSB

299

MIX_DEFAULT_CHANNELS: int = 2

300

MIX_MAX_VOLUME: int = 128

301

302

# Mixer initialization flags

303

MIX_INIT_FLAC: int = 0x00000001

304

MIX_INIT_MOD: int = 0x00000002

305

MIX_INIT_MP3: int = 0x00000008

306

MIX_INIT_OGG: int = 0x00000010

307

MIX_INIT_MID: int = 0x00000020

308

MIX_INIT_OPUS: int = 0x00000040

309

310

# Music types

311

MUS_NONE: int = 0

312

MUS_CMD: int = 1

313

MUS_WAV: int = 2

314

MUS_MOD: int = 3

315

MUS_MID: int = 4

316

MUS_OGG: int = 5

317

MUS_MP3: int = 6

318

MUS_MP3_MAD_UNUSED: int = 7

319

MUS_FLAC: int = 8

320

MUS_MODPLUG_UNUSED: int = 9

321

MUS_OPUS: int = 10

322

323

class Mix_Chunk:

324

"""Audio chunk structure."""

325

allocated: int # 1 if allocated, 0 if not

326

abuf: ctypes.POINTER(ctypes.c_uint8) # Audio buffer

327

alen: int # Audio buffer length

328

volume: int # Volume (0-128)

329

330

class Mix_Music:

331

"""Opaque music structure."""

332

```

333

334

### Audio Callbacks and Effects

335

336

Advanced audio processing functions.

337

338

```python { .api }

339

def Mix_RegisterEffect(chan: int, f: ctypes.CFUNCTYPE, d: ctypes.CFUNCTYPE, arg: ctypes.c_void_p) -> int:

340

"""Register audio effect function."""

341

342

def Mix_UnregisterEffect(channel: int, f: ctypes.CFUNCTYPE) -> int:

343

"""Unregister audio effect function."""

344

345

def Mix_UnregisterAllEffects(channel: int) -> int:

346

"""Unregister all effects on channel."""

347

348

def Mix_SetPostMix(mix_func: ctypes.CFUNCTYPE, arg: ctypes.c_void_p) -> None:

349

"""Set post-mix callback function."""

350

351

def Mix_HookMusic(mix_func: ctypes.CFUNCTYPE, arg: ctypes.c_void_p) -> None:

352

"""Set music hook callback function."""

353

354

def Mix_HookMusicFinished(music_finished: ctypes.CFUNCTYPE) -> None:

355

"""Set callback for when music finishes."""

356

357

def Mix_ChannelFinished(channel_finished: ctypes.CFUNCTYPE) -> None:

358

"""Set callback for when channel finishes."""

359

```

360

361

## Usage Examples

362

363

### Basic Sound Playback

364

365

```python

366

import sdl2

367

import sdl2.sdlmixer

368

369

# Initialize SDL2 with audio

370

sdl2.SDL_Init(sdl2.SDL_INIT_AUDIO)

371

372

# Initialize mixer

373

if sdl2.sdlmixer.Mix_OpenAudio(22050, sdl2.sdlmixer.MIX_DEFAULT_FORMAT, 2, 1024) == -1:

374

print("Failed to initialize mixer")

375

exit(1)

376

377

# Load sound effect

378

sound = sdl2.sdlmixer.Mix_LoadWAV(b"sound.wav")

379

if not sound:

380

print("Failed to load sound")

381

exit(1)

382

383

# Load background music

384

music = sdl2.sdlmixer.Mix_LoadMUS(b"music.ogg")

385

if not music:

386

print("Failed to load music")

387

exit(1)

388

389

# Play background music

390

sdl2.sdlmixer.Mix_PlayMusic(music, -1) # Loop forever

391

392

# Main loop

393

running = True

394

event = sdl2.SDL_Event()

395

396

while running:

397

while sdl2.SDL_PollEvent(event):

398

if event.type == sdl2.SDL_QUIT:

399

running = False

400

elif event.type == sdl2.SDL_KEYDOWN:

401

if event.key.keysym.sym == sdl2.SDLK_SPACE:

402

# Play sound effect

403

sdl2.sdlmixer.Mix_PlayChannel(-1, sound, 0)

404

405

# Cleanup

406

sdl2.sdlmixer.Mix_FreeChunk(sound)

407

sdl2.sdlmixer.Mix_FreeMusic(music)

408

sdl2.sdlmixer.Mix_CloseAudio()

409

sdl2.SDL_Quit()

410

```

411

412

### Low-Level Audio Device Control

413

414

```python

415

import sdl2

416

import ctypes

417

418

def audio_callback(userdata, stream, length):

419

"""Audio callback function."""

420

# Fill stream with audio data

421

# This example just fills with silence

422

ctypes.memset(stream, 0, length)

423

424

# Initialize SDL2

425

sdl2.SDL_Init(sdl2.SDL_INIT_AUDIO)

426

427

# Set up audio specification

428

audio_spec = sdl2.SDL_AudioSpec()

429

audio_spec.freq = 44100

430

audio_spec.format = sdl2.AUDIO_S16LSB

431

audio_spec.channels = 2

432

audio_spec.samples = 1024

433

audio_spec.callback = audio_callback

434

audio_spec.userdata = None

435

436

# Open audio device

437

obtained = sdl2.SDL_AudioSpec()

438

device_id = sdl2.SDL_OpenAudioDevice(None, 0, audio_spec, obtained, 0)

439

440

if device_id == 0:

441

print("Failed to open audio device")

442

exit(1)

443

444

print(f"Opened audio device {device_id}")

445

print(f"Format: {obtained.format}, Freq: {obtained.freq}, Channels: {obtained.channels}")

446

447

# Start audio playback

448

sdl2.SDL_PauseAudioDevice(device_id, 0)

449

450

# Run for a while

451

sdl2.SDL_Delay(5000)

452

453

# Stop and close

454

sdl2.SDL_PauseAudioDevice(device_id, 1)

455

sdl2.SDL_CloseAudioDevice(device_id)

456

sdl2.SDL_Quit()

457

```

458

459

### Audio Format Conversion

460

461

```python

462

import sdl2

463

import ctypes

464

465

# Initialize SDL2

466

sdl2.SDL_Init(sdl2.SDL_INIT_AUDIO)

467

468

# Set up conversion from 16-bit stereo to 8-bit mono

469

cvt = sdl2.SDL_AudioCVT()

470

result = sdl2.SDL_BuildAudioCVT(

471

cvt,

472

sdl2.AUDIO_S16LSB, 2, 44100, # Source: 16-bit stereo 44.1kHz

473

sdl2.AUDIO_U8, 1, 22050 # Dest: 8-bit mono 22.05kHz

474

)

475

476

if result == -1:

477

print("Audio conversion not possible")

478

exit(1)

479

elif result == 0:

480

print("No conversion needed")

481

exit(0)

482

483

# Allocate buffer for conversion (example with 1024 samples)

484

original_len = 1024 * 2 * 2 # 1024 samples * 2 channels * 2 bytes per sample

485

cvt.len = original_len

486

cvt.buf = (ctypes.c_uint8 * (original_len * cvt.len_mult))()

487

488

# Fill buffer with sample data (normally you'd load from file)

489

# ... fill cvt.buf with audio data ...

490

491

# Perform conversion

492

if sdl2.SDL_ConvertAudio(cvt) == 0:

493

print(f"Conversion successful. New length: {cvt.len_cvt}")

494

else:

495

print("Conversion failed")

496

497

sdl2.SDL_Quit()

498

```

499

500

### Volume and Effects Control

501

502

```python

503

import sdl2

504

import sdl2.sdlmixer

505

506

# Initialize SDL2 and mixer

507

sdl2.SDL_Init(sdl2.SDL_INIT_AUDIO)

508

sdl2.sdlmixer.Mix_OpenAudio(44100, sdl2.sdlmixer.MIX_DEFAULT_FORMAT, 2, 1024)

509

510

# Load sound

511

sound = sdl2.sdlmixer.Mix_LoadWAV(b"sound.wav")

512

513

# Set channel volume to 50%

514

sdl2.sdlmixer.Mix_Volume(0, sdl2.sdlmixer.MIX_MAX_VOLUME // 2)

515

516

# Play sound on channel 0

517

channel = sdl2.sdlmixer.Mix_PlayChannel(0, sound, 0)

518

519

# Wait for sound to finish

520

while sdl2.sdlmixer.Mix_Playing(channel):

521

sdl2.SDL_Delay(100)

522

523

# Play with fade-in effect

524

sdl2.sdlmixer.Mix_FadeInChannelTimed(0, sound, 0, 1000, 5000) # 1s fade-in, 5s total

525

526

# Cleanup

527

sdl2.sdlmixer.Mix_FreeChunk(sound)

528

sdl2.sdlmixer.Mix_CloseAudio()

529

sdl2.SDL_Quit()

530

```