Claude Code for winsound: Python Windows Audio and Beep — Claude Skills 360 Blog
Blog / AI / Claude Code for winsound: Python Windows Audio and Beep
AI

Claude Code for winsound: Python Windows Audio and Beep

Published: January 11, 2029
Read time: 5 min read
By: Claude Skills 360

Python’s winsound module (Windows only) plays tones and WAV audio through the system sound driver. import winsound. Beep: winsound.Beep(frequency, duration) — plays a pure tone; frequency 37–32767 Hz, duration milliseconds; blocks until finished. WAV file: winsound.PlaySound("alert.wav", winsound.SND_FILENAME) — synchronous. Async: winsound.PlaySound("alert.wav", winsound.SND_FILENAME | winsound.SND_ASYNC) — returns immediately and plays in background. Memory: winsound.PlaySound(wav_bytes, winsound.SND_MEMORY) — play WAV from bytes object. Stop: winsound.PlaySound(None, winsound.SND_PURGE) — stop any currently playing sound. Loop: winsound.PlaySound("loop.wav", winsound.SND_FILENAME | winsound.SND_LOOP | winsound.SND_ASYNC). System sounds: winsound.MessageBeep(winsound.MB_OK) — play the system beep for a message box type; constants: MB_OK, MB_ICONWARNING, MB_ICONERROR, MB_ICONQUESTION, MB_ICONASTERISK. Claude Code generates Windows desktop alert systems, progress notifications, error sounds, installer audio feedback, and Windows application sound themes.

CLAUDE.md for winsound

## winsound Stack
- Stdlib: import winsound   (Windows only)
- Beep:   winsound.Beep(440, 500)                          # 440Hz for 500ms
- File:   winsound.PlaySound("alert.wav", winsound.SND_FILENAME)
- Async:  winsound.PlaySound("bg.wav", winsound.SND_FILENAME | winsound.SND_ASYNC)
- Stop:   winsound.PlaySound(None, winsound.SND_PURGE)
- System: winsound.MessageBeep(winsound.MB_ICONERROR)
- Memory: winsound.PlaySound(wav_bytes, winsound.SND_MEMORY)

winsound Audio Pipeline

# app/winsoundutil.py — tones, alerts, WAV builder, notification system
from __future__ import annotations

import os
import struct
import time
import wave
from dataclasses import dataclass, field
from io import BytesIO
from pathlib import Path
from typing import Callable

# Only import winsound on Windows
_WINSOUND_AVAILABLE = False
if os.name == "nt":
    try:
        import winsound as _ws
        _WINSOUND_AVAILABLE = True
    except ImportError:
        pass


# ─────────────────────────────────────────────────────────────────────────────
# 1. Tone generation helpers
# ─────────────────────────────────────────────────────────────────────────────

def beep(frequency: int, duration_ms: int) -> None:
    """
    Play a beep at the given frequency (Hz) for duration_ms milliseconds.
    No-op on non-Windows platforms.

    Example:
        beep(440, 500)    # A4 note for half a second
        beep(880, 200)    # A5 note for 200ms
    """
    if _WINSOUND_AVAILABLE:
        _ws.Beep(max(37, min(32767, frequency)), max(1, duration_ms))


def beep_sequence(notes: "list[tuple[int, int]]", gap_ms: int = 50) -> None:
    """
    Play a sequence of (frequency, duration_ms) notes.

    Example:
        # Play a rising arpeggio
        beep_sequence([(262, 150), (330, 150), (392, 150), (523, 300)])
    """
    for freq, dur in notes:
        beep(freq, dur)
        if gap_ms > 0:
            time.sleep(gap_ms / 1000)


def alert_beep(kind: str = "info") -> None:
    """
    Play a pre-defined alert beep pattern.
    kind: 'info' | 'warning' | 'error' | 'success' | 'question'

    Example:
        alert_beep("error")
        alert_beep("success")
    """
    patterns: dict[str, list[tuple[int, int]]] = {
        "info":     [(880, 100), (1100, 100)],
        "warning":  [(600, 200), (500, 300)],
        "error":    [(400, 300), (300, 400)],
        "success":  [(523, 100), (659, 100), (784, 200)],
        "question": [(880, 150), (1100, 150)],
    }
    notes = patterns.get(kind, patterns["info"])
    beep_sequence(notes, gap_ms=30)


# ─────────────────────────────────────────────────────────────────────────────
# 2. System sound shortcuts
# ─────────────────────────────────────────────────────────────────────────────

def system_beep(level: str = "default") -> None:
    """
    Play a Windows system message beep.
    level: 'default' | 'info' | 'warning' | 'error' | 'question'

    Example:
        system_beep("error")
    """
    if not _WINSOUND_AVAILABLE:
        return
    mapping = {
        "default":  _ws.MB_OK,
        "info":     _ws.MB_ICONASTERISK,
        "warning":  _ws.MB_ICONEXCLAMATION,
        "error":    _ws.MB_ICONHAND,
        "question": _ws.MB_ICONQUESTION,
    }
    _ws.MessageBeep(mapping.get(level, _ws.MB_OK))


# ─────────────────────────────────────────────────────────────────────────────
# 3. WAV file playback helpers
# ─────────────────────────────────────────────────────────────────────────────

def play_wav(path: "str | Path", async_: bool = False) -> None:
    """
    Play a WAV file synchronously (default) or asynchronously.

    Example:
        play_wav("notification.wav")
        play_wav("background.wav", async_=True)  # non-blocking
    """
    if not _WINSOUND_AVAILABLE:
        return
    flags = _ws.SND_FILENAME
    if async_:
        flags |= _ws.SND_ASYNC
    _ws.PlaySound(str(path), flags)


def play_wav_bytes(wav_data: bytes, async_: bool = False) -> None:
    """
    Play WAV audio from a bytes object in memory.

    Example:
        wav_data = Path("alert.wav").read_bytes()
        play_wav_bytes(wav_data)
    """
    if not _WINSOUND_AVAILABLE:
        return
    flags = _ws.SND_MEMORY
    if async_:
        flags |= _ws.SND_ASYNC
    _ws.PlaySound(wav_data, flags)


def stop_sound() -> None:
    """Stop any currently playing sound."""
    if _WINSOUND_AVAILABLE:
        _ws.PlaySound(None, _ws.SND_PURGE)


# ─────────────────────────────────────────────────────────────────────────────
# 4. Minimal WAV generator (no third-party deps)
# ─────────────────────────────────────────────────────────────────────────────

import math


def generate_sine_wav(
    frequency: float,
    duration_s: float,
    sample_rate: int = 44100,
    amplitude: float = 0.5,
) -> bytes:
    """
    Generate a simple sine-wave WAV as bytes (PCM 16-bit mono).

    Example:
        data = generate_sine_wav(440.0, 0.5)
        play_wav_bytes(data)
    """
    n_samples = int(sample_rate * duration_s)
    buf = BytesIO()
    with wave.open(buf, "wb") as wf:
        wf.setnchannels(1)
        wf.setsampwidth(2)   # 16-bit
        wf.setframerate(sample_rate)

        frames: list[bytes] = []
        max_amp = int(32767 * amplitude)
        # Fade-in/out ramp to avoid clicks (5ms each)
        fade_samples = min(int(sample_rate * 0.005), n_samples // 4)
        for i in range(n_samples):
            sample = max_amp * math.sin(2 * math.pi * frequency * i / sample_rate)
            if i < fade_samples:
                sample *= i / fade_samples
            elif i >= n_samples - fade_samples:
                sample *= (n_samples - i) / fade_samples
            frames.append(struct.pack("<h", int(sample)))
        wf.writeframes(b"".join(frames))

    return buf.getvalue()


# ─────────────────────────────────────────────────────────────────────────────
# 5. Notification helper
# ─────────────────────────────────────────────────────────────────────────────

@dataclass
class SoundNotifier:
    """
    Play audio notifications for application events.
    Falls back gracefully on non-Windows platforms.

    Example:
        notifier = SoundNotifier()
        notifier.on_start()
        # ... do work ...
        notifier.on_complete()
        notifier.on_error()
    """
    use_system_sounds: bool = True
    volume: float = 0.5   # 0.0–1.0 for generated beeps

    def on_start(self) -> None:
        """Notify that a task has started."""
        if self.use_system_sounds:
            system_beep("info")
        else:
            beep_sequence([(523, 80), (659, 80)], gap_ms=20)

    def on_complete(self) -> None:
        """Notify that a task completed successfully."""
        if self.use_system_sounds:
            system_beep("default")
        else:
            beep_sequence([(523, 80), (659, 80), (784, 200)], gap_ms=20)

    def on_error(self) -> None:
        """Notify that a task failed."""
        if self.use_system_sounds:
            system_beep("error")
        else:
            alert_beep("error")

    def on_warning(self) -> None:
        """Notify that a warning occurred."""
        if self.use_system_sounds:
            system_beep("warning")
        else:
            alert_beep("warning")


# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    print("=== winsound demo ===")
    print(f"  Windows available: {_WINSOUND_AVAILABLE}")

    if _WINSOUND_AVAILABLE:
        print("\n--- beep (880Hz, 200ms) ---")
        beep(880, 200)

        print("\n--- beep_sequence (rising arpeggio) ---")
        beep_sequence([(262, 100), (330, 100), (392, 100), (523, 200)], gap_ms=30)

        print("\n--- alert_beep ---")
        for kind in ["info", "success", "warning", "error"]:
            print(f"  {kind}...")
            alert_beep(kind)
            time.sleep(0.3)

        print("\n--- system_beep ---")
        system_beep("info")
        time.sleep(0.2)
        system_beep("error")

    # ── generate_sine_wav (works on all platforms) ────────────────────────────
    print("\n--- generate_sine_wav ---")
    for freq, dur, name in [(440, 0.3, "A4"), (880, 0.3, "A5"), (1320, 0.3, "E6")]:
        data = generate_sine_wav(freq, dur)
        print(f"  {name} ({freq}Hz, {dur}s): {len(data)} bytes WAV")
        if _WINSOUND_AVAILABLE:
            play_wav_bytes(data)
            time.sleep(dur + 0.1)

    print("\n=== done ===")

For the playsound / simpleaudio (PyPI) alternatives — playsound("alert.mp3") supports MP3 and WAV on Windows/macOS/Linux; simpleaudio.WaveObject.from_wave_file("alert.wav").play() offers non-blocking WAV playback on all platforms — use playsound or simpleaudio for cross-platform audio in end-user applications; use winsound when you need zero dependencies on Windows and only need beeps or WAV playback. For the pygame.mixer (PyPI) alternative — pygame.mixer.Sound("alert.ogg").play() supports OGG, WAV, and MP3 with volume control, channel mixing, and precise timing — use pygame.mixer when your application already uses pygame (games, multimedia tools) or needs fine-grained audio control; use winsound for simple Windows notifications with no install overhead. The Claude Skills 360 bundle includes winsound skill sets covering beep()/beep_sequence()/alert_beep() tone helpers, system_beep() MessageBeep wrapper, play_wav()/play_wav_bytes()/stop_sound() playback utilities, generate_sine_wav() minimal PCM generator, and SoundNotifier event-driven notification system. Start with the free tier to try Windows audio patterns and winsound pipeline code generation.

Keep Reading

AI

Claude Code for email.contentmanager: Python Email Content Accessors

Read and write EmailMessage body content with Python's email.contentmanager module and Claude Code — email contentmanager ContentManager for the class that maps content types to get and set handler functions allowing EmailMessage to support get_content and set_content with type-specific behaviour, email contentmanager raw_data_manager for the ContentManager instance that handles raw bytes and str payloads without any conversion, email contentmanager content_manager for the standard ContentManager instance used by email.policy.default that intelligently handles text plain text html multipart and binary content types, email contentmanager get_content_text for the handler that returns the decoded text payload of a text-star message part as a str, email contentmanager get_content_binary for the handler that returns the raw decoded bytes payload of a non-text message part, email contentmanager get_data_manager for the get-handler lookup used by EmailMessage get_content to find the right reader function for the content type, email contentmanager set_content text for the handler that creates and sets a text part correctly choosing charset and transfer encoding, email contentmanager set_content bytes for the handler that creates and sets a binary part with base64 encoding and optional filename Content-Disposition, email contentmanager EmailMessage get_content for the method that reads the message body using the registered content manager handlers, email contentmanager EmailMessage set_content for the method that sets the message body and MIME headers in one call, email contentmanager EmailMessage make_alternative make_mixed make_related for the methods that convert a simple message into a multipart container, email contentmanager EmailMessage add_attachment for the method that attaches a file or bytes to a multipart message, and email contentmanager integration with email.message and email.policy and email.mime and io for building high-level email readers attachment extractors text body accessors HTML readers and policy-aware MIME construction pipelines.

5 min read Feb 12, 2029
AI

Claude Code for email.charset: Python Email Charset Encoding

Control header and body encoding for international email with Python's email.charset module and Claude Code — email charset Charset for the class that wraps a character set name with the encoding rules for header encoding and body encoding describing how to encode text for that charset in email messages, email charset Charset header_encoding for the attribute specifying whether headers using this charset should use QP quoted-printable encoding BASE64 encoding or no encoding, email charset Charset body_encoding for the attribute specifying the Content-Transfer-Encoding to use for message bodies in this charset such as QP or BASE64, email charset Charset output_codec for the attribute giving the Python codec name used to encode the string to bytes for the wire format, email charset Charset input_codec for the attribute giving the Python codec name used to decode incoming bytes to str, email charset Charset get_output_charset for returning the output charset name, email charset Charset header_encode for encoding a header string using the charset's header_encoding method, email charset Charset body_encode for encoding body content using the charset's body_encoding, email charset Charset convert for converting a string from the input_codec to the output_codec, email charset add_charset for registering a new charset with custom encoding rules in the global charset registry, email charset add_alias for adding an alias name that maps to an existing registered charset, email charset add_codec for registering a codec name mapping for use by the charset machinery, and email charset integration with email.message and email.mime and email.policy and email.encoders for building international email senders non-ASCII header encoders Content-Transfer-Encoding selectors charset-aware message constructors and MIME encoding pipelines.

5 min read Feb 11, 2029
AI

Claude Code for email.utils: Python Email Address and Header Utilities

Parse and format RFC 2822 email addresses and dates with Python's email.utils module and Claude Code — email utils parseaddr for splitting a display-name plus angle-bracket address string into a realname and email address tuple, email utils formataddr for combining a realname and address string into a properly quoted RFC 2822 address with angle brackets, email utils getaddresses for parsing a list of raw address header strings each potentially containing multiple comma-separated addresses into a list of realname address tuples, email utils parsedate for parsing an RFC 2822 date string into a nine-tuple compatible with time.mktime, email utils parsedate_tz for parsing an RFC 2822 date string into a ten-tuple that includes the UTC offset timezone in seconds, email utils parsedate_to_datetime for parsing an RFC 2822 date string into an aware datetime object with timezone, email utils formatdate for formatting a POSIX timestamp or the current time as an RFC 2822 date string with optional usegmt and localtime flags, email utils format_datetime for formatting a datetime object as an RFC 2822 date string, email utils make_msgid for generating a globally unique Message-ID string with optional idstring and domain components, email utils decode_rfc2231 for decoding an RFC 2231 encoded parameter value into a tuple of charset language and value, email utils encode_rfc2231 for encoding a string as an RFC 2231 encoded parameter value, email utils collapse_rfc2231_value for collapsing a decoded RFC 2231 tuple to a Unicode string, and email utils integration with email.message and email.headerregistry and datetime and time for building address parsers date formatters message-id generators header extractors and RFC-compliant email construction utilities.

5 min read Feb 10, 2029

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free