//! Multi-track song format with synthesized notes and audio file clips.
//!
//! Loads `.track` text files, schedules notes and audio clips on per-track
//! mixers, and plays them through a `SoundSystem`. Designed to be edited by
//! humans or AI and used as runtime audio in games.
//!
//! # Example
//! ```no_run
//! # #[cfg(feature = "playback")]
//! # {
//! use game_audio::{SoundSystem, track::SongPlayer};
//!
//! let system = SoundSystem::new();
//! let mut player = SongPlayer::new();
//! player.play_path(&system, "song.track").unwrap();
//! # }
//! ```
//!
//! Parsing, song data, synthesis ([`Note`]), playback (`SongPlayer`) and
//! offline rendering ([`render_song_stereo`]/[`render_song_stems`]) are
//! available on all targets — on wasm the player renders each song to a buffer
//! and drives it through Web Audio, and a host encodes the rendered samples
//! itself. The device-facing types (`SongPlayer`, `SoundSystem`) sit behind
//! the default `playback` feature; disabling it gives a headless build that
//! parses, renders and exports without an audio device. Filesystem loading
//! (`play_path`, `play_graph_path`), URL imports and WAV/MP3 file writing need
//! a native target; on wasm the host loads and parses `.track` sources itself
//! and calls `SongPlayer::play`, and [`resolve_imports`] merges only bundled
//! `std:` imports (skipping filesystem and URL imports).

mod export;
mod format;
mod graph;
#[cfg(feature = "midi")]
mod midi;
#[cfg(feature = "playback")]
mod mixer;
mod player;
mod serialize;
mod song;
#[cfg(feature = "speech")]
mod speech;
#[cfg(feature = "speech")]
pub use speech::{SungClip, sing_note};
mod synth;

#[cfg(all(not(target_arch = "wasm32"), feature = "export"))]
pub use export::{ExportError, export_mp3, export_stems, export_wav};
pub use export::{
    render_song_stems, render_song_stems_with, render_song_stereo, render_song_stereo_with,
};
pub use format::{
    ParseError, parse, parse_with_sounds, resolve_imports, resolve_imports_async,
    resolve_imports_with,
};
#[cfg(feature = "midi")]
pub use midi::{MidiImport, MidiImportError, song_from_midi};
pub use song::{
    Arpeggio, Articulation, Compare, Condition, ConditionSource, Curve, Effect, Envelope, Harmonic,
    Import, Jump, Layer, Modulation, MotifInstance, MotifNote, Note, NoteInfo, NoteOverride,
    NoteSegment, Refresh, STANDARD_WAVEFORMS, Slide, Song, Sound, Subtitle, Tempo, TimeSignature,
    Trim, Tuning, UnknownSection, VoiceKnob, VoiceOverride, VolumeBinding, WavePoint,
    default_instrument, is_audio_filename, pitch_to_frequency, pitch_to_frequency_in, ramp_curve,
    ramp_offset, sample_envelope, sample_wave, standard_waveform, volume_ramp, volume_ramp_target,
};
pub use synth::{Voice, VoiceHandle};
pub use {
    graph::SongGraph,
    player::{
        MuteSolo, PlayerError, sample_oneshot, sample_oneshot_varied, sound_oneshot,
        sound_oneshot_varied, sound_sustained, wave_oscillator,
    },
};
#[cfg(feature = "playback")]
pub use {mixer::Levels, player::SongPlayer};
