<!-- generated by epythet -->

# arioso

Unified Python facade for AI music generation.

One interface, many backends. Arioso wraps 16 AI music generation platforms —
from local open-source models to commercial REST APIs — behind a single `generate()` call.

## Install

```default
pip install arioso
```

## Quick start

```python
import arioso

# Generate music (defaults to MusicGen, runs locally)
song = arioso.generate("upbeat jazz piano")

# The result is a Song object with audio data
song.audio.audio_array  # numpy array (for local models)
song.audio.sample_rate  # e.g. 32000

# Use a different platform
song = arioso.generate("epic orchestral soundtrack", platform="elevenlabs", duration=30)
song.audio.audio_bytes  # MP3 bytes
```

## Enhance existing audio (audio-to-audio)

Beyond text-to-music, arioso can transform audio you already have – e.g. turn a
plain synthesized/”MIDI” render into something richer, or re-generate music that
follows an input melody. This is the `enhance()` entry point:

```python
import arioso

rendered = (
    ...
)  # a Song, a file path, bytes, an (array, sample_rate) pair, or a numpy waveform

# Audio-to-audio: continue/transform the input (Stable Audio Open, local)
better = arioso.enhance(rendered, "warm analog studio band", platform="stable_audio")

# Subtle variation: low strength keeps the input, high lets the prompt take over
# (Stable Audio 2.5 on fal.ai; needs FAL_KEY)
close = arioso.enhance(
    rendered, "full symphony orchestra", platform="stable_audio_25", strength=0.3
)

# Remix toward style tags (ACE-Step on fal.ai)
remix = arioso.enhance(rendered, "orchestral, film score, brass", platform="ace_step")

# Melody-conditioned: keep the tune, take the style from the prompt (MusicGen-melody)
variation = arioso.enhance(rendered, "energetic EDM", platform="musicgen")

# Discover which platforms accept input audio
arioso.supports_audio_input("stable_audio")  # True
arioso.supports_audio_input("mubert")  # False
```

`enhance(audio, prompt='', *, platform='stable_audio', strength=None, as_='auto')`
routes your audio into the platform’s audio-conditioning affordance
(`audio_input`, `melody`, or `reference_audio`) and generates. Input audio is
accepted in any form a `Song`/`AudioResult`/`bytes`/path/`(array, sample_rate)`/
numpy-waveform can take (normalized internally). Note that `stable_audio` via
diffusers uses the input as an initial waveform (continuation/init) and has no
`strength` knob (a value passed there is ignored with a warning); for a
strength-controlled transform use `stable_audio_25`.

## Platforms

16 platforms are included, spanning local models, REST APIs, and SDK-based services:

| Platform                   | Access                          | Auth                                 | Install                               |
|----------------------------|---------------------------------|--------------------------------------|---------------------------------------|
| **MusicGen**               | Local (audiocraft/transformers) | None                                 | `pip install arioso[musicgen]`        |
| **Stable Audio Open**      | Local (diffusers)               | None                                 | `pip install arioso[stable-audio]`    |
| **Harmonai**               | Local (diffusers)               | None                                 | `pip install arioso[harmonai]`        |
| **Riffusion**              | Local (diffusers)               | None                                 | `pip install arioso[riffusion]`       |
| **ElevenLabs**             | REST API                        | `ELEVENLABS_API_KEY`                 | `pip install arioso[elevenlabs]`      |
| **Suno** (via sunoapi.org) | REST API                        | `SUNO_API_KEY`                       | `pip install arioso[sunoapi]`         |
| **Google Lyria 2**         | REST (Vertex AI)                | `GOOGLE_CLOUD_PROJECT` + gcloud auth | `pip install arioso[lyria2]`          |
| **Google Lyria RT**        | WebSocket (genai SDK)           | `GOOGLE_API_KEY`                     | `pip install arioso[lyria-rt]`        |
| **Mubert**                 | REST API                        | `MUBERT_PAT`                         | `pip install arioso[mubert]`          |
| **Beatoven.ai**            | REST API                        | `BEATOVEN_API_KEY`                   | `pip install arioso[beatoven]`        |
| **Loudly**                 | REST API                        | `LOUDLY_API_KEY`                     | `pip install arioso[loudly]`          |
| **Jen**                    | REST API                        | `JEN_API_KEY`                        | `pip install arioso[jen]`             |
| **YuE**                    | fal.ai / local CLI              | `FAL_KEY`                            | `pip install arioso[yue]`             |
| **Stable Audio 2.5**       | fal.ai                          | `FAL_KEY`                            | `pip install arioso[stable-audio-25]` |
| **ACE-Step**               | fal.ai                          | `FAL_KEY`                            | `pip install arioso[ace-step]`        |
| **Udio**                   | Unofficial wrapper              | `UDIO_AUTH_COOKIE`                   | `pip install arioso[udio]`            |
```python
# See what's available
arioso.list_platforms()
# ['beatoven', 'elevenlabs', 'harmonai', 'jen', 'loudly', 'lyria2', ...]

# Inspect a platform's configuration
arioso.get_platform_info("musicgen")
```

### MusicGen (local, no API key)

Runs on your machine. Tries `audiocraft` first, falls back to HuggingFace `transformers`.

```python
song = arioso.generate(
    "chill lofi beats",
    platform="musicgen",
    duration=10,
    temperature=0.8,
    guidance=3.0,
    model="facebook/musicgen-small",  # or medium, large, melody
)
```

### ElevenLabs

Needs `ELEVENLABS_API_KEY` environment variable.

```python
song = arioso.generate(
    "dramatic film score",
    platform="elevenlabs",
    duration=60,
    instrumental=True,
    output_format="mp3_44100_128",
)

# With lyrics
song = arioso.generate(
    "pop ballad",
    platform="elevenlabs",
    lyrics="[Verse]\nWalking through the rain\n[Chorus]\nI found my way home",
    title="Coming Home",
)
```

### Suno (via sunoapi.org)

Needs `SUNO_API_KEY` environment variable.

```python
songs = arioso.generate_many(
    "summer reggae vibes",
    platform="sunoapi",
    genre="reggae, tropical",
    instrumental=True,
)
# Suno returns 2 songs per call
for song in songs:
    print(song.title, song.audio_url)
```

## Parameters

All platforms share a common vocabulary of parameter names. Use any that
the platform supports — unsupported ones are warned about and ignored.

```python
song = arioso.generate(
    "ambient soundscape",  # prompt (required)
    platform="musicgen",
    duration=15,  # seconds
    temperature=1.2,  # sampling randomness
    top_k=250,  # top-k sampling
    guidance=3.0,  # classifier-free guidance
    seed=42,  # reproducibility
)
```

The full set of unified parameter names (42):

| Parameter       | Type   | Description                         |
|-----------------|--------|-------------------------------------|
| `prompt`        | str    | Text description of desired music   |
| `duration`      | float  | Output length in seconds            |
| `lyrics`        | str    | Custom lyrics text                  |
| `instrumental`  | bool   | Force instrumental-only output      |
| `genre`         | str    | Genre tag or category               |
| `title`         | str    | Song title                          |
| `model`         | str    | Model version or variant            |
| `seed`          | int    | Random seed for reproducibility     |
| `guidance`      | float  | Classifier-free guidance scale      |
| `temperature`   | float  | Sampling randomness                 |
| `top_k`         | int    | Top-k sampling parameter            |
| `top_p`         | float  | Top-p (nucleus) sampling            |
| `bpm`           | int    | Beats per minute                    |
| `key`           | str    | Musical key (e.g. “C major”)        |
| `energy`        | float  | Energy/intensity level 0-1          |
| `output_format` | str    | Desired output format               |
| …               |        | See `arioso.AFFORDANCES` for all 40 |

Each platform maps these to its native parameter names automatically.
For example, `instrumental=True` becomes `make_instrumental=True` for Suno
and `force_instrumental=True` for ElevenLabs.

## Output

Every call returns a `Song` object:

```python
song = arioso.generate("jazz piano", platform="musicgen")

song.status  # 'complete'
song.platform  # 'musicgen'
song.title  # ''
song.metadata  # {'model': 'facebook/musicgen-small', ...}

# Audio is in song.audio (an AudioResult)
song.audio.audio_array  # numpy array (local models)
song.audio.audio_bytes  # raw bytes (REST APIs)
song.audio.audio_url  # URL string (Suno)
song.audio.sample_rate  # e.g. 32000
song.audio.format  # 'wav', 'mp3', etc.

# Shortcuts
song.audio_array  # same as song.audio.audio_array
song.audio_bytes  # same as song.audio.audio_bytes
song.sample_rate  # same as song.audio.sample_rate
```

Use `generate_many()` when you want all results (some platforms return multiple):

```python
songs = arioso.generate_many("pop song", platform="sunoapi")
# Returns list[Song]
```

## Adding a new platform

Arioso uses a plugin architecture. Each platform is a subfolder under
`arioso/platforms/` with two files:

```default
arioso/platforms/myplatform/
    __init__.py
    config.py        # required: declares PLATFORM_CONFIG
    adapter.py       # optional: custom generation logic
```

### Minimal example (REST API)

For a REST API, you may only need `config.py`:

```python
# arioso/platforms/myplatform/config.py

PLATFORM_CONFIG = {
    "name": "myplatform",
    "display_name": "My Platform",
    "website": "https://myplatform.com",
    "tier": "simple",
    "access_type": "rest_api",
    "auth": {
        "type": "bearer_token",
        "env_var": "MYPLATFORM_API_KEY",
    },
    "param_map": {
        "prompt": {"native_name": "text", "required": True},
        "duration": {"native_name": "length_seconds"},
    },
    "supported_affordances": ["prompt", "duration"],
    "on_unsupported_param": "warn",
    "output": {
        "default_format": "mp3",
        "sample_rate": 44100,
        "returns": "bytes",
    },
    "api": {
        "base_url": "https://api.myplatform.com",
        "generate_endpoint": {"method": "post", "path": "/v1/generate"},
    },
}
```

The platform is auto-discovered on the next `arioso.list_platforms()` call.

### Custom adapter (Python library)

For platforms that are Python libraries rather than REST APIs, add an `adapter.py`:

```python
# arioso/platforms/myplatform/adapter.py

from arioso.base import Song, AudioResult


class Adapter:
    def __init__(self, config):
        self.config = config

    def generate(self, prompt, *, duration=10, **kwargs):
        # Your generation logic here
        from some_library import generate_audio

        audio = generate_audio(prompt, length=duration)

        return Song(
            audio=AudioResult(audio_array=audio, sample_rate=44100, format="wav"),
            platform="myplatform",
            status="complete",
        )
```

### Manual registration

Third-party packages can register platforms at runtime:

```python
from arioso.registry import register_platform

register_platform("custom", my_config_dict, my_adapter_instance)
```

## Platforms Without Public APIs

The following platforms were considered during the design of arioso’s unified
parameter vocabulary and affordance system, but do not have public APIs (nor a
reliable third-party API wrapper). They are listed here for completeness.

| Platform       | Website                                  | What It Does                                                                                           | Affordances Considered                 |
|----------------|------------------------------------------|--------------------------------------------------------------------------------------------------------|----------------------------------------|
| **AIVA**       | [aiva.ai](https://aiva.ai)               | Orchestral AI composition. Desktop/web DAW with 250+ style presets, direct BPM/key/instrument control. | genre, bpm, key, instruments, duration |
| **ACE Studio** | [acestudio.ai](https://acestudio.ai)     | AI vocal synthesis DAW plugin. 140+ voice models for singing voice generation.                         | voice_id, lyrics, instruments          |
| **Boomy**      | [boomy.com](https://boomy.com)           | AI song creation with Auto Vocal and streaming platform distribution. Enterprise-only API.             | prompt, voice_id, instrumental         |
| **Soundraw**   | [soundraw.io](https://soundraw.io)       | AI music generation for content creators. Enterprise B2B API only ($11/mo consumer web app).           | genre, duration, energy                |
| **CassetteAI** | [cassetteai.com](https://cassetteai.com) | Prompt-based music generation. Web-only, no known API.                                                 | prompt, duration                       |
| **Musicfy**    | [musicfy.lol](https://musicfy.lol)       | AI music generation with voice cloning and pitch shifting. Web-only, no known API.                     | prompt, voice_id, pitch_shift          |

## Research & Background

Arioso’s design is informed by extensive research into the AI music generation
landscape. Two reference documents in [`misc/docs/`]() provide the
full background:

### Platform comparison and API landscape

[**AI Music Generation Tools: A Unified API Reference for 21 Platforms**]()
maps the full union of capabilities across every tool we investigated. Highlights:

- [General characteristics comparison]() —
  pricing, API availability, max length, sample rate, vocal support, and quality tier for 18 tools
- [Documentation and integration links]() —
  docs URLs, OpenAPI specs, Python/JS SDKs, and MCP servers per platform
- [Feature affordance matrix]() —
  which platforms support text prompts, negative prompts, lyrics, audio conditioning, melody conditioning, duration, BPM, key, genre tags, energy, instruments, and more
- [Unified affordance mapping]() —
  the 40 common parameter names that arioso exposes, with native parameter names per platform
- [Complete API parameter catalogs]() —
  full endpoint and parameter documentation for Suno, ElevenLabs, MusicGen, Lyria RealTime, Stable Audio Open, and YuE

### Prompt engineering across platforms

[**Prompt Engineering for Music AI Generation: A Resource Guide**]()
compiles 78 resources (papers, datasets, tools, taxonomies, and guides) covering
how to write effective prompts for text-to-music systems. Key sections:

- [Papers on prompt engineering techniques]() —
  chain-of-thought prompting, prompt tuning, user studies, and structured prompting strategies
- [Model architecture and text encoders]() —
  how T5, CLAP, FLAN-T5, and MuLan encoders determine which prompt styles work best
- [Text-audio alignment models]() —
  CLAP, MuLan, LAION-CLAP, and how they shape the vocabulary space
- [CFG and parameter interactions]() —
  how guidance scale, temperature, and other parameters interact with text prompts
- [Captioning datasets defining vocabulary]() —
  MusicCaps, LP-MusicCaps, MusicBench, and 11 other datasets that trained these models
- [Vocabulary and taxonomy resources]() —
  AudioSet ontology, Music Ontology, Cyanite AI taxonomy
- [Platform-specific prompt guides]() —
  official and community guides for Stable Audio, Udio, Lyria, Suno, ElevenLabs, and more

Each platform also has a `<PLATFORM>_REFERENCE.md` in its directory under
`arioso/platforms/` with platform-specific prompt engineering guidance, API
details, and links to further reading.

## Architecture

```default
arioso/
    __init__.py          # Facade: generate(), list_platforms()
    base.py              # Song, AudioResult, AFFORDANCES (42 unified params)
    registry.py          # Auto-discovery, lazy loading, manual registration
    translation.py       # Parameter renaming & coercion (common -> native)
    _util.py             # Auth helpers, HTTP session factory

    platforms/
        _base_adapter.py   # BaseRestAdapter (shared REST infrastructure)
        musicgen/          # Local inference via audiocraft/transformers
        stable_audio/      # Local inference via diffusers
        harmonai/          # Unconditional generation via Dance Diffusion
        riffusion/         # Spectrogram-based via diffusers
        elevenlabs/        # REST with OpenAPI spec via ho
        sunoapi/           # REST via sunoapi.org
        lyria2/            # Google Vertex AI REST
        lyria_rt/          # Google Lyria RealTime WebSocket
        mubert/            # Mubert REST API
        beatoven/          # Beatoven.ai REST API
        loudly/            # Loudly REST API
        jen/               # Jen REST API
        yue/               # YuE via fal.ai or local CLI
        stable_audio_25/   # Stable Audio 2.5 via fal.ai (audio-to-audio with strength)
        ace_step/          # ACE-Step via fal.ai (tags -> music, audio remix)
        udio/              # Udio via unofficial wrapper
```

Key design choices:

- **Zero required dependencies.** The core package imports nothing outside stdlib.
  Platform dependencies are lazy-imported when you first call `generate()`.
- **Config-driven plugins.** Each platform declares a `PLATFORM_CONFIG` dict with
  parameter mappings, auth scheme, endpoints, and output format. Adding a platform
  is mostly configuration.
- **Automatic parameter translation.** The translation layer renames unified
  affordance names to native platform names and applies type coercions
  (e.g. `duration` seconds to `music_length_ms` milliseconds for ElevenLabs)
  for platforms served by the config-generated REST adapter. A platform with its
  own `adapter.py` takes unified names directly, on every path
  (`arioso.generate` and `arioso.services.<platform>.generate` alike).
- **Leverages existing libraries.** Uses
  [ho](https://github.com/i2mint/ho) for OpenAPI-to-Python-function generation,
  [i2](https://github.com/i2mint/i2) for signature manipulation and function wrapping.

<p class="epythet-aggregates">This documentation as a single file: <a href="arioso.md">arioso.md</a> (Markdown, for agents).</p>
