"""Type stubs for coremusic.capi module.

This module provides low-level Python bindings to CoreAudio frameworks
via Cython. All functions are thin wrappers around C APIs.
"""

from typing import Any, Dict, List, Optional, Tuple, Union

# ============================================================================
# Base Classes
# ============================================================================

class CoreAudioObject:
    """Base class for CoreAudio objects with automatic resource management."""

    object_id: int
    is_disposed: bool

    def __init__(self) -> None: ...
    def _set_object_id(self, object_id: int) -> None: ...
    def _ensure_not_disposed(self) -> None: ...
    def dispose(self) -> None: ...

class AudioPlayer:
    """Audio player implementation with callback infrastructure."""
    def __init__(self, link_session: Any = None) -> None: ...
    def load_file(self, file_path: str) -> int: ...
    def setup_output(self) -> int: ...
    def start(self) -> int: ...
    def play(self) -> int: ...
    def stop(self) -> int: ...
    def set_looping(self, loop: bool) -> None: ...
    def reset_playback(self) -> None: ...
    def is_playing(self) -> bool: ...
    def get_progress(self) -> float: ...
    @property
    def link_session(self) -> Any: ...
    def get_link_timing(self, quantum: float = 4.0) -> Optional[Dict[str, Any]]: ...

class AudioRecorder:
    """Audio recorder implementation using AudioQueue."""
    def __init__(self, sample_rate: int = 44100, channels: int = 2) -> None: ...
    def setup_input(self, duration: float) -> int: ...
    def start(self) -> int: ...
    def stop(self) -> int: ...
    def is_recording(self) -> bool: ...
    def get_progress(self) -> float: ...
    def get_recorded_frames(self) -> int: ...
    def get_recorded_duration(self) -> float: ...
    def run_loop(self, seconds: float = 0.1) -> None: ...
    def save_to_file(self, file_path: str) -> None: ...
    def get_data(self) -> bytes: ...
    def has_audio_content(self) -> bool: ...
    @property
    def sample_rate(self) -> int: ...
    @property
    def channels(self) -> int: ...

# ============================================================================
# FourCC Conversion
# ============================================================================

def fourchar_to_int(fourcc: str) -> int:
    """Convert a four-character code string to integer."""
    ...

def int_to_fourchar(value: int) -> str:
    """Convert an integer to four-character code string."""
    ...

# ============================================================================
# Audio File Operations
# ============================================================================

def audio_file_open_url(file_path: str) -> int:
    """Open an audio file and return file ID."""
    ...

def audio_file_close(file_id: int) -> None:
    """Close an audio file."""
    ...

def audio_file_get_property(file_id: int, property_id: int) -> bytes:
    """Get a property from an audio file."""
    ...

def audio_file_read_packets(
    file_id: int, start_packet: int, packet_count: int
) -> Tuple[bytes, int]:
    """Read audio packets from file. Returns (data, actual_count)."""
    ...

def audio_file_read_packets_into(
    file_id: int, start_packet: int, packet_count: int, buffer: bytearray
) -> Tuple[int, int]:
    """Read packets directly into a provided buffer (zero-copy).

    High-performance variant that reads directly into a caller-provided buffer,
    avoiding memory allocation and copying.

    Args:
        file_id: AudioFile ID from audio_file_open_url()
        start_packet: Starting packet number
        packet_count: Number of packets to read
        buffer: Pre-allocated buffer (bytearray or numpy array) to read into

    Returns:
        Tuple of (bytes_read, packets_read)
    """
    ...

# ============================================================================
# Audio File Stream Operations
# ============================================================================

def audio_file_stream_open() -> int:
    """Open an audio file stream."""
    ...

def audio_file_stream_close(stream_id: int) -> None:
    """Close an audio file stream."""
    ...

def audio_file_stream_parse_bytes(stream_id: int, data: bytes, flags: int = 0) -> int:
    """Parse audio data bytes."""
    ...

def audio_file_stream_parse_buffer(
    stream_id: int, data: Union[bytes, bytearray], flags: int = 0
) -> int:
    """Parse buffer data through the AudioFileStream parser (zero-copy).

    High-performance variant that accepts any buffer object without copying.

    Args:
        stream_id: AudioFileStream ID
        data: Audio data (bytes, bytearray, or numpy uint8 array)
        flags: Parse flags (default 0)

    Returns:
        OSStatus code (0 for success)
    """
    ...

def audio_file_stream_seek(stream_id: int, packet_offset: int) -> None:
    """Seek to packet offset in stream."""
    ...

def audio_file_stream_get_property(stream_id: int, property_id: int) -> bytes:
    """Get a property from audio file stream."""
    ...

def audio_file_stream_get_property_ready_to_produce_packets(stream_id: int) -> bool:
    """Check if stream is ready to produce packets."""
    ...

# ============================================================================
# Audio Queue Operations
# ============================================================================

def audio_queue_new_output(format_dict: Dict[str, Any]) -> int:
    """Create a new output audio queue."""
    ...

def audio_queue_allocate_buffer(queue_id: int, buffer_size: int) -> int:
    """Allocate an audio buffer."""
    ...

def audio_queue_enqueue_buffer(queue_id: int, buffer_id: int) -> None:
    """Enqueue an audio buffer."""
    ...

def audio_queue_start(queue_id: int) -> None:
    """Start the audio queue."""
    ...

def audio_queue_stop(queue_id: int, immediate: bool) -> None:
    """Stop the audio queue."""
    ...

def audio_queue_dispose(queue_id: int, immediate: bool) -> None:
    """Dispose of an audio queue."""
    ...

# ============================================================================
# Audio Component & AudioUnit Operations
# ============================================================================

def audio_component_find_next(description: Dict[str, Any], previous_component_id: int = 0) -> Optional[int]:
    """Find next matching audio component."""
    ...

def audio_component_instance_new(component_id: int) -> int:
    """Create new instance of audio component."""
    ...

def audio_component_instance_dispose(instance_id: int) -> None:
    """Dispose of audio component instance."""
    ...

def audio_component_copy_name(component_id: int) -> Optional[str]:
    """Get the name of an audio component."""
    ...

def audio_component_get_description(component_id: int) -> Dict[str, Any]:
    """Get the description of an audio component."""
    ...

def audio_unit_initialize(unit_id: int) -> None:
    """Initialize an AudioUnit."""
    ...

def audio_unit_uninitialize(unit_id: int) -> None:
    """Uninitialize an AudioUnit."""
    ...

def audio_unit_get_property(
    unit_id: int, property_id: int, scope: int, element: int
) -> bytes:
    """Get a property from AudioUnit."""
    ...

def audio_unit_set_property(
    unit_id: int, property_id: int, scope: int, element: int, data: bytes
) -> None:
    """Set a property on AudioUnit."""
    ...

def audio_output_unit_start(unit_id: int) -> None:
    """Start AudioUnit output."""
    ...

def audio_output_unit_stop(unit_id: int) -> None:
    """Stop AudioUnit output."""
    ...

def audio_unit_find_all_components(
    component_type: Optional[str] = None,
    component_subtype: Optional[str] = None,
    manufacturer: Optional[str] = None
) -> List[int]:
    """Find all AudioComponent IDs matching criteria."""
    ...

def audio_unit_get_component_info(component_id: int) -> Dict[str, Any]:
    """Get component info dict with keys: name, type, subtype, manufacturer, version."""
    ...

def audio_unit_get_parameter_list(
    audio_unit_id: int, scope: int = 0, element: int = 0
) -> List[int]:
    """Get list of parameter IDs."""
    ...

def audio_unit_get_parameter_info(
    audio_unit_id: int, param_id: int, scope: int = 0
) -> Dict[str, Any]:
    """Get parameter info dict with metadata."""
    ...

def audio_unit_get_parameter(
    audio_unit_id: int, param_id: int, scope: int = 0, element: int = 0
) -> float:
    """Get current parameter value."""
    ...

def audio_unit_set_parameter(
    audio_unit_id: int, param_id: int, value: float, scope: int = 0, element: int = 0
) -> None:
    """Set parameter value."""
    ...

def audio_unit_get_factory_presets(audio_unit_id: int) -> List[Dict[str, Any]]:
    """Get list of factory preset dicts with keys: number, name."""
    ...

def audio_unit_set_current_preset(audio_unit_id: int, preset_number: int) -> None:
    """Load a factory preset by number."""
    ...

def audio_unit_render(
    audio_unit_id: int,
    input_data: bytes,
    num_frames: int,
    sample_rate: float,
    num_channels: int
) -> bytes:
    """Render audio through the AudioUnit."""
    ...

def audio_unit_render_into(
    audio_unit_id: int,
    input_data: Union[bytes, bytearray],
    output_buffer: bytearray,
    num_frames: int,
    num_channels: int = 2
) -> int:
    """Process audio through an AudioUnit directly into provided buffers (zero-copy).

    Args:
        audio_unit_id: AudioUnit instance ID
        input_data: Input audio data (bytes, bytearray, or numpy uint8 array)
        output_buffer: Pre-allocated output buffer (bytearray or numpy uint8 array)
        num_frames: Number of frames to process
        num_channels: Number of channels (default 2)

    Returns:
        Number of bytes written to output_buffer
    """
    ...

# ============================================================================
# Audio Hardware & Device Operations
# ============================================================================

def audio_hardware_get_devices() -> List[int]:
    """Get all audio device IDs."""
    ...

def audio_hardware_get_default_output_device() -> int:
    """Get default output device ID."""
    ...

def audio_hardware_get_default_input_device() -> int:
    """Get default input device ID."""
    ...

def audio_hardware_destroy_aggregate_device(device_id: int) -> None:
    """Destroy an aggregate device."""
    ...

def audio_hardware_unload() -> None:
    """Unload audio hardware."""
    ...

def audio_object_get_property_data(
    object_id: int, property_id: int, scope: int, element: int
) -> bytes:
    """Get property data from an AudioObject."""
    ...

def audio_object_show(object_id: int) -> None:
    """Display information about an AudioObject."""
    ...

# ============================================================================
# Audio Services Operations
# ============================================================================

def audio_services_create_system_sound_id(file_url: str) -> int:
    """Create a system sound ID."""
    ...

def audio_services_dispose_system_sound_id(sound_id: int) -> None:
    """Dispose of a system sound ID."""
    ...

def audio_services_play_system_sound(sound_id: int) -> None:
    """Play a system sound."""
    ...

def audio_services_play_alert_sound(sound_id: int) -> None:
    """Play an alert sound."""
    ...

def audio_services_get_property(
    property_id: int, specifier_size: int, specifier: bytes
) -> bytes:
    """Get an AudioServices property."""
    ...

def audio_services_set_property(
    property_id: int, specifier_size: int, specifier: bytes, data: bytes
) -> None:
    """Set an AudioServices property."""
    ...

# ============================================================================
# MIDI Operations
# ============================================================================

def midi_client_create(name: str) -> int:
    """Create a MIDI client."""
    ...

def midi_client_dispose(client_id: int) -> None:
    """Dispose of a MIDI client."""
    ...

def midi_input_port_create(client_id: int, name: str) -> int:
    """Create a MIDI input port."""
    ...

def midi_output_port_create(client_id: int, name: str) -> int:
    """Create a MIDI output port."""
    ...

def midi_port_dispose(port_id: int) -> None:
    """Dispose of a MIDI port."""
    ...

def midi_port_connect_source(port_id: int, source_id: int) -> None:
    """Connect MIDI port to source."""
    ...

def midi_port_disconnect_source(port_id: int, source_id: int) -> None:
    """Disconnect MIDI port from source."""
    ...

def midi_send(port_id: int, destination_id: int, data: bytes, timestamp: int) -> None:
    """Send MIDI data."""
    ...

def create_midi_note_message(
    channel: int, note: int, velocity: int, release_velocity: int, duration: float
) -> bytes:
    """Create a MIDI note message."""
    ...

def create_midi_channel_message(status: int, data1: int, data2: int) -> bytes:
    """Create a MIDI channel message."""
    ...

# ============================================================================
# Music Player & Sequence Operations
# ============================================================================

def dispose_music_player(player_id: int) -> None:
    """Dispose of a music player."""
    ...

def dispose_music_sequence(sequence_id: int) -> None:
    """Dispose of a music sequence."""
    ...

def create_music_device_note_params(pitch: float, velocity: float) -> bytes:
    """Create music device note parameters."""
    ...

def create_music_device_std_note_params(pitch: int, velocity: int) -> bytes:
    """Create standard music device note parameters."""
    ...

def demonstrate_callback_infrastructure() -> None:
    """Demonstrate callback infrastructure (for testing)."""
    ...

# ============================================================================
# Property ID Getters - Audio File
# ============================================================================

def get_audio_file_property_data_format() -> int: ...
def get_audio_file_property_audio_data_packet_count() -> int: ...
def get_audio_file_property_estimated_duration() -> int: ...
def get_audio_file_property_maximum_packet_size() -> int: ...
def get_audio_file_read_permission() -> int: ...

# ============================================================================
# Property ID Getters - Audio File Stream
# ============================================================================

def get_audio_file_stream_property_ready_to_produce_packets() -> int: ...
def get_audio_file_stream_property_data_format() -> int: ...
def get_audio_file_stream_property_audio_data_byte_count() -> int: ...
def get_audio_file_stream_property_audio_data_packet_count() -> int: ...
def get_audio_file_stream_property_average_bytes_per_packet() -> int: ...
def get_audio_file_stream_property_bit_rate() -> int: ...
def get_audio_file_stream_property_byte_to_packet() -> int: ...
def get_audio_file_stream_property_channel_layout() -> int: ...
def get_audio_file_stream_property_data_offset() -> int: ...
def get_audio_file_stream_property_file_format() -> int: ...
def get_audio_file_stream_property_format_list() -> int: ...
def get_audio_file_stream_property_frame_to_packet() -> int: ...
def get_audio_file_stream_property_info_dictionary() -> int: ...
def get_audio_file_stream_property_magic_cookie_data() -> int: ...
def get_audio_file_stream_property_maximum_packet_size() -> int: ...
def get_audio_file_stream_property_packet_size_upper_bound() -> int: ...
def get_audio_file_stream_property_packet_table_info() -> int: ...
def get_audio_file_stream_property_packet_to_byte() -> int: ...
def get_audio_file_stream_property_packet_to_frame() -> int: ...

# Error codes
def get_audio_file_stream_error_unspecified_error() -> int: ...
def get_audio_file_stream_error_unsupported_file_type() -> int: ...
def get_audio_file_stream_error_unsupported_data_format() -> int: ...
def get_audio_file_stream_error_unsupported_property() -> int: ...
def get_audio_file_stream_error_bad_property_size() -> int: ...
def get_audio_file_stream_error_not_optimized() -> int: ...
def get_audio_file_stream_error_invalid_packet_offset() -> int: ...
def get_audio_file_stream_error_invalid_file() -> int: ...
def get_audio_file_stream_error_value_unknown() -> int: ...
def get_audio_file_stream_error_data_unavailable() -> int: ...
def get_audio_file_stream_error_illegal_operation() -> int: ...
def get_audio_file_stream_error_discontinuity_cant_recover() -> int: ...

# Flags
def get_audio_file_stream_parse_flag_discontinuity() -> int: ...
def get_audio_file_stream_property_flag_cache_property() -> int: ...
def get_audio_file_stream_property_flag_property_is_cached() -> int: ...
def get_audio_file_stream_seek_flag_offset_is_estimated() -> int: ...

# ============================================================================
# Property ID Getters - AudioUnit
# ============================================================================

def get_audio_unit_property_stream_format() -> int: ...
def get_audio_unit_property_sample_rate() -> int: ...
def get_audio_unit_property_latency() -> int: ...
def get_audio_unit_property_cpu_load() -> int: ...
def get_audio_unit_property_maximum_frames_per_slice() -> int: ...
def get_audio_unit_property_parameter_list() -> int: ...
def get_audio_unit_scope_global() -> int: ...
def get_audio_unit_scope_input() -> int: ...
def get_audio_unit_scope_output() -> int: ...

# ============================================================================
# Property ID Getters - Audio Device
# ============================================================================

def get_audio_device_property_device_uid() -> int: ...
def get_audio_device_property_model_uid() -> int: ...
def get_audio_device_property_transport_type() -> int: ...
def get_audio_device_property_device_is_alive() -> int: ...
def get_audio_device_property_nominal_sample_rate() -> int: ...
def get_audio_device_property_available_nominal_sample_rates() -> int: ...
def get_audio_device_property_is_hidden() -> int: ...
def get_audio_device_property_preferred_channels_for_stereo() -> int: ...
def get_audio_device_property_stream_configuration() -> int: ...
def get_audio_object_property_name() -> int: ...
def get_audio_object_property_manufacturer() -> int: ...
def get_audio_object_property_element_name() -> int: ...
def get_audio_object_property_element_main() -> int: ...
def get_audio_object_property_scope_global() -> int: ...
def get_audio_object_property_scope_input() -> int: ...
def get_audio_object_property_scope_output() -> int: ...

# ============================================================================
# Format & Type Getters
# ============================================================================

def get_audio_format_linear_pcm() -> int: ...
def get_audio_file_wave_type() -> int: ...
def get_audio_component_type_music_device() -> int: ...

# ============================================================================
# Audio Converter Operations (MISSING)
# ============================================================================

def audio_converter_new(
    source_format: Dict[str, Any], dest_format: Dict[str, Any]
) -> int:
    """Create a new audio converter."""
    ...

def audio_converter_dispose(converter_id: int) -> None:
    """Dispose of an audio converter."""
    ...

def audio_converter_convert_buffer(converter_id: int, input_data: bytes) -> bytes:
    """Convert audio data buffer."""
    ...

def audio_converter_convert_buffer_into(
    converter_id: int, input_data: Union[bytes, bytearray], output_buffer: bytearray
) -> int:
    """Convert audio data directly into a provided output buffer (zero-copy).

    High-performance variant that accepts memoryview/buffer input and writes
    directly to a caller-provided output buffer.

    Args:
        converter_id: AudioConverter ID from audio_converter_new()
        input_data: Input audio data (bytes, bytearray, or numpy array)
        output_buffer: Pre-allocated output buffer (bytearray or numpy array)

    Returns:
        Number of bytes written to output_buffer
    """
    ...

def audio_converter_get_property(converter_id: int, property_id: int) -> bytes:
    """Get a property from audio converter."""
    ...

def audio_converter_set_property(
    converter_id: int, property_id: int, data: bytes
) -> None:
    """Set a property on audio converter."""
    ...

def audio_converter_reset(converter_id: int) -> None:
    """Reset audio converter."""
    ...

def audio_converter_fill_complex_buffer(
    converter_id: int,
    input_data: bytes,
    input_packet_count: int,
    output_packet_count: int,
    source_format_dict: Dict[str, Any]
) -> Tuple[bytes, int]:
    """Convert audio using callback-based API for complex conversions."""
    ...

def audio_converter_fill_complex_buffer_into(
    converter_id: int,
    input_data: Union[bytes, bytearray],
    output_buffer: bytearray,
    input_packet_count: int,
    output_packet_count: int,
    source_format_dict: Dict[str, Any]
) -> Tuple[int, int]:
    """Convert audio using callback-based API directly into provided buffers (zero-copy).

    Args:
        converter_id: AudioConverter ID
        input_data: Input audio data (bytes, bytearray, or numpy uint8 array)
        output_buffer: Pre-allocated output buffer (bytearray or numpy uint8 array)
        input_packet_count: Number of packets in input data
        output_packet_count: Number of output packets to produce
        source_format_dict: Source AudioStreamBasicDescription as dict

    Returns:
        Tuple of (bytes_written, actual_packet_count)
    """
    ...

# ============================================================================
# Extended Audio File Operations (MISSING)
# ============================================================================

def extended_audio_file_open_url(file_path: str) -> int:
    """Open an extended audio file."""
    ...

def extended_audio_file_create_with_url(
    file_path: str,
    file_type: int,
    source_format: Dict[str, Any],
    channel_layout: Optional[bytes],
    flags: int,
) -> int:
    """Create a new extended audio file."""
    ...

def extended_audio_file_dispose(ext_file_id: int) -> None:
    """Dispose of an extended audio file."""
    ...

def extended_audio_file_read(ext_file_id: int, num_frames: int) -> Tuple[bytes, int]:
    """Read frames from extended audio file."""
    ...

def extended_audio_file_read_into(
    ext_file_id: int, num_frames: int, buffer: bytearray, num_channels: int = 2
) -> Tuple[int, int]:
    """Read frames directly into a provided buffer (zero-copy).

    Args:
        ext_file_id: ExtAudioFile ID
        num_frames: Number of frames to read
        buffer: Pre-allocated buffer (bytearray or numpy uint8 array)
        num_channels: Number of audio channels (default 2)

    Returns:
        Tuple of (bytes_read, frames_read)
    """
    ...

def extended_audio_file_write(
    ext_file_id: int, num_frames: int, audio_data: bytes
) -> None:
    """Write frames to extended audio file."""
    ...

def extended_audio_file_get_property(ext_file_id: int, property_id: int) -> bytes:
    """Get a property from extended audio file."""
    ...

def extended_audio_file_set_property(
    ext_file_id: int, property_id: int, data: bytes
) -> None:
    """Set a property on extended audio file."""
    ...

# ============================================================================
# AUGraph Operations (MISSING)
# ============================================================================

def au_graph_new() -> int:
    """Create a new AUGraph."""
    ...

def au_graph_dispose(graph_id: int) -> None:
    """Dispose of an AUGraph."""
    ...

def au_graph_open(graph_id: int) -> None:
    """Open an AUGraph."""
    ...

def au_graph_close(graph_id: int) -> None:
    """Close an AUGraph."""
    ...

def au_graph_initialize(graph_id: int) -> None:
    """Initialize an AUGraph."""
    ...

def au_graph_uninitialize(graph_id: int) -> None:
    """Uninitialize an AUGraph."""
    ...

def au_graph_start(graph_id: int) -> None:
    """Start an AUGraph."""
    ...

def au_graph_stop(graph_id: int) -> None:
    """Stop an AUGraph."""
    ...

def au_graph_is_open(graph_id: int) -> bool:
    """Check if AUGraph is open."""
    ...

def au_graph_is_initialized(graph_id: int) -> bool:
    """Check if AUGraph is initialized."""
    ...

def au_graph_is_running(graph_id: int) -> bool:
    """Check if AUGraph is running."""
    ...

def au_graph_add_node(graph_id: int, description: Dict[str, int]) -> int:
    """Add a node to AUGraph."""
    ...

def au_graph_remove_node(graph_id: int, node: int) -> None:
    """Remove a node from AUGraph."""
    ...

def au_graph_get_node_count(graph_id: int) -> int:
    """Get number of nodes in AUGraph."""
    ...

def au_graph_get_ind_node(graph_id: int, index: int) -> int:
    """Get node at index in AUGraph."""
    ...

def au_graph_node_info(graph_id: int, node: int) -> int:
    """Get AudioUnit for node in AUGraph."""
    ...

def au_graph_connect_node_input(
    graph_id: int, source_node: int, source_output: int, dest_node: int, dest_input: int
) -> None:
    """Connect nodes in AUGraph."""
    ...

def au_graph_disconnect_node_input(
    graph_id: int, dest_node: int, dest_input: int
) -> None:
    """Disconnect node input in AUGraph."""
    ...

def au_graph_clear_connections(graph_id: int) -> None:
    """Clear all connections in AUGraph."""
    ...

def au_graph_update(graph_id: int) -> bool:
    """Update AUGraph configuration."""
    ...

def au_graph_get_cpu_load(graph_id: int) -> float:
    """Get CPU load for AUGraph."""
    ...

def au_graph_get_max_cpu_load(graph_id: int) -> float:
    """Get maximum CPU load for AUGraph."""
    ...

# ============================================================================
# Music Player & Sequence Operations (MISSING)
# ============================================================================

def new_music_player() -> int:
    """Create a new music player."""
    ...

def new_music_sequence() -> int:
    """Create a new music sequence."""
    ...

def music_player_set_sequence(player_id: int, sequence_id: int) -> None:
    """Set sequence for music player."""
    ...

def music_player_get_sequence(player_id: int) -> int:
    """Get sequence from music player."""
    ...

def music_player_set_time(player_id: int, time: float) -> None:
    """Set playback time."""
    ...

def music_player_get_time(player_id: int) -> float:
    """Get current playback time."""
    ...

def music_player_preroll(player_id: int) -> None:
    """Preroll music player."""
    ...

def music_player_start(player_id: int) -> None:
    """Start music player."""
    ...

def music_player_stop(player_id: int) -> None:
    """Stop music player."""
    ...

def music_player_is_playing(player_id: int) -> bool:
    """Check if music player is playing."""
    ...

def music_player_set_play_rate_scalar(player_id: int, rate: float) -> None:
    """Set play rate scalar."""
    ...

def music_player_get_play_rate_scalar(player_id: int) -> float:
    """Get play rate scalar."""
    ...

def music_sequence_new_track(sequence_id: int) -> int:
    """Create a new track in sequence."""
    ...

def music_sequence_dispose_track(sequence_id: int, track_id: int) -> None:
    """Dispose of a track."""
    ...

def music_sequence_get_track_count(sequence_id: int) -> int:
    """Get number of tracks."""
    ...

def music_sequence_get_ind_track(sequence_id: int, index: int) -> int:
    """Get track at index."""
    ...

def music_sequence_get_tempo_track(sequence_id: int) -> int:
    """Get tempo track."""
    ...

def music_sequence_set_sequence_type(sequence_id: int, seq_type: int) -> None:
    """Set sequence type."""
    ...

def music_sequence_get_sequence_type(sequence_id: int) -> int:
    """Get sequence type."""
    ...

def music_sequence_file_load(
    sequence_id: int, file_path: str, file_type_hint: int, flags: int
) -> None:
    """Load sequence from file."""
    ...

def music_track_new_midi_note_event(
    track_id: int, timestamp: float, note_message: bytes
) -> None:
    """Add MIDI note event to track."""
    ...

def music_track_new_midi_channel_event(
    track_id: int, timestamp: float, channel_message: bytes
) -> None:
    """Add MIDI channel event to track."""
    ...

def music_track_new_extended_tempo_event(
    track_id: int, timestamp: float, bpm: float
) -> None:
    """Add tempo event to track."""
    ...

def music_device_midi_event(
    unit_id: int, status: int, data1: int, data2: int, offset_sample_frame: int
) -> None:
    """Send MIDI event to music device."""
    ...

def music_device_start_note(
    unit_id: int,
    instrument_id: int,
    group_id: int,
    note_params: bytes,
    offset_sample_frame: int,
) -> int:
    """Start a note on music device."""
    ...

def music_device_stop_note(
    unit_id: int, group_id: int, note_instance_id: int, offset_sample_frame: int
) -> None:
    """Stop a note on music device."""
    ...

def music_device_sysex(unit_id: int, data: bytes) -> None:
    """Send SysEx to music device."""
    ...

# ============================================================================
# Additional MIDI Operations (MISSING - 65 functions)
# ============================================================================

def midi_object_get_string_property(obj_id: int, property_id: str) -> str:
    """Get string property from MIDI object."""
    ...

def midi_object_get_integer_property(obj_id: int, property_id: str) -> int:
    """Get integer property from MIDI object."""
    ...

def midi_object_set_string_property(obj_id: int, property_id: str, value: str) -> None:
    """Set string property on MIDI object."""
    ...

def midi_object_set_integer_property(obj_id: int, property_id: str, value: int) -> None:
    """Set integer property on MIDI object."""
    ...

def midi_object_get_name(obj_id: int) -> str:
    """Get name of MIDI object."""
    ...

def midi_object_get_manufacturer(obj_id: int) -> str:
    """Get manufacturer of MIDI object."""
    ...

def midi_object_get_model(obj_id: int) -> str:
    """Get model of MIDI object."""
    ...

def midi_get_device(device_index: int) -> int:
    """Get MIDI device by index."""
    ...

def midi_get_number_of_devices() -> int:
    """Get number of MIDI devices."""
    ...

def midi_device_get_number_of_entities(device_id: int) -> int:
    """Get number of entities in device."""
    ...

def midi_device_get_entity(device_id: int, entity_index: int) -> int:
    """Get entity from device."""
    ...

def midi_device_get_name(device_id: int) -> str:
    """Get device name."""
    ...

def midi_entity_get_number_of_sources(entity_id: int) -> int:
    """Get number of sources in entity."""
    ...

def midi_entity_get_source(entity_id: int, source_index: int) -> int:
    """Get source from entity."""
    ...

def midi_entity_get_number_of_destinations(entity_id: int) -> int:
    """Get number of destinations in entity."""
    ...

def midi_entity_get_destination(entity_id: int, dest_index: int) -> int:
    """Get destination from entity."""
    ...

def midi_entity_get_name(entity_id: int) -> str:
    """Get entity name."""
    ...

def midi_endpoint_get_name(endpoint_id: int) -> str:
    """Get endpoint name."""
    ...

def midi_endpoint_dispose(endpoint_id: int) -> None:
    """Dispose of endpoint."""
    ...

def midi_source_create(client_id: int, name: str) -> int:
    """Create virtual MIDI source."""
    ...

def midi_destination_create(client_id: int, name: str) -> int:
    """Create virtual MIDI destination."""
    ...

def midi_send_data(port_id: int, dest_id: int, data: bytes, timestamp: int) -> None:
    """Send MIDI data."""
    ...

def midi_note_on(channel: int, note: int, velocity: int) -> Tuple[int, int, int]:
    """Create MIDI note on message. Returns (status, data1, data2)."""
    ...

def midi_note_off(channel: int, note: int, velocity: int = 0) -> Tuple[int, int, int]:
    """Create MIDI note off message. Returns (status, data1, data2)."""
    ...

def midi_control_change(channel: int, controller: int, value: int) -> Tuple[int, int, int]:
    """Create MIDI control change message. Returns (status, data1, data2)."""
    ...

def midi_program_change(channel: int, program: int) -> Tuple[int, int, int]:
    """Create MIDI program change message. Returns (status, data1, data2)."""
    ...

def midi_pitch_bend(channel: int, value: int) -> Tuple[int, int, int]:
    """Create MIDI pitch bend message. Returns (status, data1, data2)."""
    ...

# MIDI 2.0 UMP Functions
def midi1_up_note_on(group: int, channel: int, note: int, velocity: int) -> int:
    """Create MIDI 1.0 UMP note on."""
    ...

def midi1_up_note_off(group: int, channel: int, note: int, velocity: int) -> int:
    """Create MIDI 1.0 UMP note off."""
    ...

def midi1_up_control_change(
    group: int, channel: int, controller: int, value: int
) -> int:
    """Create MIDI 1.0 UMP control change."""
    ...

def midi1_up_pitch_bend(group: int, channel: int, lsb: int, msb: int) -> int:
    """Create MIDI 1.0 UMP pitch bend."""
    ...

def midi1_up_system_common(group: int, status: int, byte1: int, byte2: int) -> int:
    """Create MIDI 1.0 UMP system common."""
    ...

def midi1_up_sysex(
    group: int,
    status: int,
    bytes_used: int,
    byte1: int,
    byte2: int,
    byte3: int,
    byte4: int,
    byte5: int,
    byte6: int,
) -> Tuple[int, int]:
    """Create MIDI 1.0 UMP SysEx."""
    ...

def midi1_up_channel_voice_message(
    group: int, status: int, channel: int, data1: int, data2: int
) -> int:
    """Create MIDI 1.0 UMP channel voice message."""
    ...

def midi2_note_on(
    group: int,
    channel: int,
    note: int,
    attribute_type: int,
    attribute_data: int,
    velocity: int,
) -> Tuple[int, int]:
    """Create MIDI 2.0 UMP note on."""
    ...

def midi2_note_off(
    group: int,
    channel: int,
    note: int,
    attribute_type: int,
    attribute_data: int,
    velocity: int,
) -> Tuple[int, int]:
    """Create MIDI 2.0 UMP note off."""
    ...

def midi2_control_change(
    group: int, channel: int, controller: int, value: int
) -> Tuple[int, int]:
    """Create MIDI 2.0 UMP control change."""
    ...

def midi2_program_change(
    group: int,
    channel: int,
    bank_valid: bool,
    program: int,
    bank_msb: int,
    bank_lsb: int,
) -> Tuple[int, int]:
    """Create MIDI 2.0 UMP program change."""
    ...

def midi2_pitch_bend(group: int, channel: int, value: int) -> Tuple[int, int]:
    """Create MIDI 2.0 UMP pitch bend."""
    ...

def midi2_channel_voice_message(
    group: int, status: int, channel: int, index: int, value: int
) -> Tuple[int, int]:
    """Create MIDI 2.0 UMP channel voice message."""
    ...

def midi_message_type_for_up_word(word: int) -> int:
    """Get message type from UMP word."""
    ...

# MIDI Device/Entity/Endpoint Management
def midi_device_create(owner: int, name: str, manufacturer: str, model: str) -> int:
    """Create MIDI device."""
    ...

def midi_device_dispose(device_id: int) -> None:
    """Dispose of MIDI device."""
    ...

def midi_device_add_entity(
    device_id: int, name: str, embedded: bool, num_sources: int, num_destinations: int
) -> int:
    """Add entity to device."""
    ...

def midi_device_new_entity(
    device_id: int,
    name: str,
    protocol: int,
    embedded: bool,
    num_sources: int,
    num_destinations: int,
) -> int:
    """Create new entity in device."""
    ...

def midi_device_remove_entity(device_id: int, entity_id: int) -> None:
    """Remove entity from device."""
    ...

def midi_entity_add_or_remove_endpoints(
    entity_id: int, num_sources: int, num_destinations: int
) -> None:
    """Add or remove endpoints in entity."""
    ...

def midi_endpoint_set_ref_cons(endpoint_id: int, ref1: Any, ref2: Any) -> None:
    """Set reference constants for endpoint."""
    ...

def midi_endpoint_get_ref_cons(endpoint_id: int) -> Tuple[Any, Any]:
    """Get reference constants from endpoint."""
    ...

# MIDI Device List Management
def midi_device_list_get_number_of_devices(device_list: int) -> int:
    """Get number of devices in list."""
    ...

def midi_device_list_get_device(device_list: int, index: int) -> int:
    """Get device from list."""
    ...

def midi_device_list_add_device(device_list: int, device_id: int) -> None:
    """Add device to list."""
    ...

def midi_device_list_dispose(device_list: int) -> None:
    """Dispose of device list."""
    ...

# MIDI Driver Functions
def midi_get_driver_io_runloop() -> Any:
    """Get driver I/O runloop."""
    ...

def midi_get_driver_device_list(driver: Any) -> int:
    """Get driver device list."""
    ...

def midi_driver_enable_monitoring(driver: Any, enabled: bool) -> None:
    """Enable/disable driver monitoring."""
    ...

# MIDI Setup Functions
def midi_setup_add_device(device_id: int) -> None:
    """Add device to setup."""
    ...

def midi_setup_remove_device(device_id: int) -> None:
    """Remove device from setup."""
    ...

def midi_setup_add_external_device(device_id: int) -> None:
    """Add external device to setup."""
    ...

def midi_setup_remove_external_device(device_id: int) -> None:
    """Remove external device from setup."""
    ...

def midi_external_device_create(name: str, manufacturer: str, model: str) -> int:
    """Create external MIDI device."""
    ...

# MIDI Thru Connection Functions
def midi_thru_connection_params_initialize(params: Any) -> None:
    """Initialize thru connection parameters."""
    ...

def midi_thru_connection_create(owner_id: str, params: bytes) -> int:
    """Create MIDI thru connection."""
    ...

def midi_thru_connection_dispose(connection_id: int) -> None:
    """Dispose of thru connection."""
    ...

def midi_thru_connection_get_params(connection_id: int) -> bytes:
    """Get thru connection parameters."""
    ...

def midi_thru_connection_set_params(connection_id: int, params: bytes) -> None:
    """Set thru connection parameters."""
    ...

def midi_thru_connection_find(owner_id: str) -> List[int]:
    """Find thru connections by owner."""
    ...

# ============================================================================
# Additional Property Constants (Hundreds of getters)
# ============================================================================

# Extended Audio File Property Constants
def get_extended_audio_file_property_file_data_format() -> int: ...
def get_extended_audio_file_property_client_data_format() -> int: ...
def get_extended_audio_file_property_file_channel_layout() -> int: ...
def get_extended_audio_file_property_client_channel_layout() -> int: ...
def get_extended_audio_file_property_codec_manufacturer() -> int: ...
def get_extended_audio_file_property_audio_file() -> int: ...
def get_extended_audio_file_property_file_length_frames() -> int: ...

# Audio Converter Property Constants
def get_audio_converter_property_min_input_buffer_size() -> int: ...
def get_audio_converter_property_min_output_buffer_size() -> int: ...
def get_audio_converter_property_max_input_packet_size() -> int: ...
def get_audio_converter_property_max_output_packet_size() -> int: ...
def get_audio_converter_property_sample_rate_converter_quality() -> int: ...
def get_audio_converter_property_codec_quality() -> int: ...
def get_audio_converter_quality_max() -> int: ...
def get_audio_converter_quality_high() -> int: ...
def get_audio_converter_quality_medium() -> int: ...
def get_audio_converter_quality_low() -> int: ...
def get_audio_converter_quality_min() -> int: ...

# AUGraph Error Constants
def get_au_graph_err_node_not_found() -> int: ...
def get_au_graph_err_invalid_connection() -> int: ...
def get_au_graph_err_output_node_err() -> int: ...
def get_au_graph_err_cannot_do_in_current_context() -> int: ...
def get_au_graph_err_invalid_audio_unit() -> int: ...

# Linear PCM Format Flags
def get_linear_pcm_format_flag_is_float() -> int: ...
def get_linear_pcm_format_flag_is_big_endian() -> int: ...
def get_linear_pcm_format_flag_is_signed_integer() -> int: ...
def get_linear_pcm_format_flag_is_packed() -> int: ...
def get_linear_pcm_format_flag_is_aligned_high() -> int: ...
def get_linear_pcm_format_flag_is_non_interleaved() -> int: ...
def get_linear_pcm_format_flag_is_non_mixable() -> int: ...

# AudioUnit Property Constants
def get_audio_unit_property_set_render_callback() -> int: ...
def get_audio_unit_manufacturer_apple() -> int: ...
def get_audio_unit_type_output() -> int: ...
def get_audio_unit_subtype_default_output() -> int: ...

# Audio Services Constants
def get_audio_services_no_error() -> int: ...
def get_audio_services_unsupported_property_error() -> int: ...
def get_audio_services_bad_property_size_error() -> int: ...
def get_audio_services_bad_specifier_size_error() -> int: ...
def get_audio_services_system_sound_unspecified_error() -> int: ...
def get_audio_services_system_sound_client_timed_out_error() -> int: ...
def get_audio_services_system_sound_exceeded_maximum_duration_error() -> int: ...
def get_audio_services_property_is_ui_sound() -> int: ...
def get_audio_services_property_complete_playback_if_app_dies() -> int: ...
def get_system_sound_id_user_preferred_alert() -> int: ...
def get_system_sound_id_flash_screen() -> int: ...
def get_user_preferred_alert() -> int: ...

# MIDI Error Constants
def get_midi_error_invalid_client() -> int: ...
def get_midi_error_invalid_port() -> int: ...
def get_midi_error_no_connection() -> int: ...
def get_midi_error_unknown_endpoint() -> int: ...
def get_midi_error_message_send_err() -> int: ...
def get_midi_error_server_start_err() -> int: ...
def get_midi_error_setup_format_err() -> int: ...
def get_midi_error_not_permitted() -> int: ...
def get_midi_error_object_not_found() -> int: ...
def get_midi_error_id_not_unique() -> int: ...
def get_midi_error_unknown_error() -> int: ...

# MIDI Channel Voice Status
def get_midi_cv_status_note_off() -> int: ...
def get_midi_cv_status_note_on() -> int: ...
def get_midi_cv_status_poly_pressure() -> int: ...
def get_midi_cv_status_control_change() -> int: ...
def get_midi_cv_status_program_change() -> int: ...
def get_midi_cv_status_channel_pressure() -> int: ...
def get_midi_cv_status_pitch_bend() -> int: ...

# MIDI Control Types
def get_midi_control_type_7bit() -> int: ...
def get_midi_control_type_14bit() -> int: ...
def get_midi_control_type_7bit_rpn() -> int: ...
def get_midi_control_type_14bit_rpn() -> int: ...
def get_midi_control_type_7bit_nrpn() -> int: ...
def get_midi_control_type_14bit_nrpn() -> int: ...

# Additional MIDI Constants
def get_midi_error_no_current_setup() -> int: ...
def get_midi_error_unknown_property() -> int: ...
def get_midi_error_wrong_endpoint_type() -> int: ...
def get_midi_error_wrong_property_type() -> int: ...
def get_midi_error_wrong_thread() -> int: ...

# MIDI Message Types
def get_midi_message_type_channel_voice1() -> int: ...
def get_midi_message_type_channel_voice2() -> int: ...
def get_midi_message_type_data128() -> int: ...
def get_midi_message_type_sysex() -> int: ...
def get_midi_message_type_system() -> int: ...
def get_midi_message_type_utility() -> int: ...

# MIDI Object Types
def get_midi_object_type_destination() -> int: ...
def get_midi_object_type_device() -> int: ...
def get_midi_object_type_entity() -> int: ...
def get_midi_object_type_external_destination() -> int: ...
def get_midi_object_type_external_device() -> int: ...
def get_midi_object_type_external_entity() -> int: ...
def get_midi_object_type_external_source() -> int: ...
def get_midi_object_type_other() -> int: ...
def get_midi_object_type_source() -> int: ...

# MIDI Properties
def get_midi_property_device_id() -> int: ...
def get_midi_property_display_name() -> int: ...
def get_midi_property_driver_owner() -> int: ...
def get_midi_property_manufacturer() -> int: ...
def get_midi_property_model() -> int: ...
def get_midi_property_name() -> int: ...
def get_midi_property_offline() -> int: ...
def get_midi_property_private() -> int: ...
def get_midi_property_receive_channels() -> int: ...
def get_midi_property_transmit_channels() -> int: ...
def get_midi_property_unique_id() -> int: ...

# MIDI Protocol
def get_midi_protocol_1_0() -> int: ...
def get_midi_protocol_2_0() -> int: ...

# MIDI Thru Connection
def get_midi_thru_connection_max_endpoints() -> int: ...

# MIDI Transform Types
def get_midi_transform_add() -> int: ...
def get_midi_transform_filter_out() -> int: ...
def get_midi_transform_map_control() -> int: ...
def get_midi_transform_map_value() -> int: ...
def get_midi_transform_max_value() -> int: ...
def get_midi_transform_min_value() -> int: ...
def get_midi_transform_none() -> int: ...
def get_midi_transform_scale() -> int: ...

# Music Device Constants
def get_music_device_midi_event_list_select() -> int: ...
def get_music_device_midi_event_select() -> int: ...
def get_music_device_range() -> int: ...
def get_music_device_start_note_select() -> int: ...
def get_music_device_stop_note_select() -> int: ...
def get_music_device_sysex_select() -> int: ...

# Music Event Types
def get_music_event_type_au_preset() -> int: ...
def get_music_event_type_extended_note() -> int: ...
def get_music_event_type_extended_tempo() -> int: ...
def get_music_event_type_meta() -> int: ...
def get_music_event_type_midi_channel_message() -> int: ...
def get_music_event_type_midi_note_message() -> int: ...
def get_music_event_type_midi_raw_data() -> int: ...
def get_music_event_type_null() -> int: ...
def get_music_event_type_parameter() -> int: ...
def get_music_event_type_user() -> int: ...

# Music Note Event Constants
def get_music_note_event_unused() -> int: ...
def get_music_note_event_use_group_instrument() -> int: ...

# Music Sequence File Types
def get_music_sequence_file_any_type() -> int: ...
def get_music_sequence_file_imelody_type() -> int: ...
def get_music_sequence_file_midi_type() -> int: ...

# Music Sequence Types
def get_music_sequence_type_beats() -> int: ...
def get_music_sequence_type_samples() -> int: ...
def get_music_sequence_type_seconds() -> int: ...

# Sequence Track Properties
def get_sequence_track_property_automated_parameters() -> int: ...
def get_sequence_track_property_loop_info() -> int: ...
def get_sequence_track_property_mute_status() -> int: ...
def get_sequence_track_property_offset_time() -> int: ...
def get_sequence_track_property_solo_status() -> int: ...
def get_sequence_track_property_time_resolution() -> int: ...
def get_sequence_track_property_track_length() -> int: ...

# System Sound IDs
def get_system_sound_id_vibrate() -> int: ...

# Additional MIDI Functions (missing from earlier sections)
def midi_get_source(source_index: int) -> int:
    """Get MIDI source by index (already listed above, keeping for completeness)."""
    ...

def midi_get_destination(dest_index: int) -> int:
    """Get MIDI destination by index (already listed above, keeping for completeness)."""
    ...

def midi_get_number_of_sources() -> int:
    """Get number of MIDI sources (already listed above, keeping for completeness)."""
    ...

def midi_get_number_of_destinations() -> int:
    """Get number of MIDI destinations (already listed above, keeping for completeness)."""
    ...

# Testing/Debugging Functions
def test_error() -> None:
    """Test error handling (debugging function)."""
    ...

# NOTE: This .pyi file now includes all ~390 functions from capi.pyx
# The functional API is comprehensive and covers all major CoreAudio frameworks:
# - CoreAudio (hardware, devices, properties)
# - AudioFile/AudioFileStream (file I/O and streaming)
# - AudioQueue (playback/recording queues)
# - AudioConverter (format conversion)
# - ExtendedAudioFile (high-level file I/O)
# - AudioComponent/AudioUnit (audio processing)
# - AudioServices (system sounds)
# - CoreMIDI (MIDI 1.0/2.0 with UMP support)
# - MusicPlayer/MusicSequence (sequencing)
# - MusicDevice (MIDI synthesis)
# - AUGraph (audio processing graphs)
