Build an audio generator
Run a small Node audio generator with a Maru account token or a configured inference service.
Build a command-line application that turns a prompt into seeded WAV files. The generation SDK handles request limits, model selection, progress, cancellation, event-stream reconnection and WAV decoding. Your application supplies credentials and decides where to save the result.
This is an experimental source-workspace example. It requires a Maru checkout with its dependencies installed. Hosted generation also requires an available inference service and Studio admission for the account. The public npm package's proposed hosted operation API is a separate integration; these examples use the existing generation gateway.
Start without an account
From the repository root:
pnpm --filter @maruaudio/website exec node --import tsx scripts/examples/generate-audio.ts \ --mode mock --prompt 'a dry glass bell' --seeds 1042,1043 \ --seconds 2 --out /tmp/maru-bells
The mock produces deterministic test tones, without a model download or a provider call. Use a new output directory for each run. The example refuses an existing directory before submitting generation.
Try a loop with the same application:
pnpm --filter @maruaudio/website exec node --import tsx scripts/examples/generate-audio.ts \ --mode mock --audio-type loop --prompt 'an evolving instrumental pad' \ --seconds 8 --seeds 1050 --out /tmp/maru-loop
Connect your Maru account
Create a personal access token on Access tokens with the
inference:run scope. Set MARU_TOKEN in your shell or secret manager.
Keep it out of source control, browser code and module state. The token belongs
to your account, and generated usage is attributed to that account.
pnpm --filter @maruaudio/website exec node --import tsx scripts/examples/generate-audio.ts \ --mode account --prompt 'a dry glass bell' --seconds 2 --seeds 1042 \ --out /tmp/maru-cloud-bell
The default account service is the Maru platform. Set MARU_API_URL to use a
development website instead. Tokens are sent only to that origin, over HTTPS
or a local loopback connection. A token needs both the inference scope and an
account admitted to Studio. Owning a token alone does not grant admission.
Account mode submits and cancels through the typed generation tRPC service.
The SDK reads the authenticated event stream and audio bytes. Your program
never receives the website's provider secret or an inference-runner token.
Connect another inference service
Set AUDIO_INFERENCE_URL to a service that implements Maru's audio inference
v2 contract, and AUDIO_INFERENCE_KEY to the key issued by its operator:
pnpm --filter @maruaudio/website exec node --import tsx scripts/examples/generate-audio.ts \ --mode service --audio-type loop --prompt 'a warm ambient instrumental loop' \ --seconds 8 --seeds 1050 --out /tmp/maru-service-loop
This service credential differs from a Stability AI provider API key. The connector handles the Stable Audio model protocol supported by that service; it does not call arbitrary provider APIs. Direct service requests do not pass through the Maru account wallet. Their operator owns usage accounting.
Build on the example
The reusable host is apps/website/scripts/examples/audio-generator.ts.
Import connectExampleGenerator and generateToDirectory from that file in a
workspace application. The command-line adapter beside it demonstrates the
minimal configuration:
const connector = await connectExampleGenerator({
mode: "account",
credential: process.env.MARU_TOKEN,
})
const result = await generateToDirectory({
connector,
out: "/tmp/my-new-take",
request: {
audioType: "one-shot",
prompt: "a soft wooden tap",
seconds: 2,
model: "auto",
seeds: [1042],
steps: 8,
},
signal: myAbortController.signal,
})
The host composes createAudioGenerationService, collectGenerationJob, the
SDK's hosted or mock connector and the shared WAV encoder. It adds no model
implementation or realtime audio path. For a module face, retain this host
boundary: the host owns credentials and inference, while the face receives
display-safe progress and prepared audio resources.
Each successful item becomes a float32 WAV. receipt.json records its seed,
model provenance, license, SHA-256 and the job's terminal outcome. Check
terminal.type and itemErrors before treating the batch as complete. Partial
results stay available when an item fails or a job is cancelled. Ctrl-C cancels
the job; the CLI also cancels after ten minutes. Service discovery has its own
SDK timeout. These outputs are candidates for audition and quality checks,
not automatically published modules or sound banks.
Credits and model usage
Usage shows account balances, audio usage and model input/output tokens. The initial token policy reuses Okslop's 0.5 credits per 1,000 input tokens and 1.5 per 1,000 output tokens, rounded up to a tenth per provider call. Model multipliers have a central override map; unlisted models use 1. Audio credits use the existing model, duration, variation and step weights.
The server owns pricing. It stores each event's policy version and quoted amount, so changing rates does not rewrite older events. Local generation is unbilled. Account credit enforcement is an operator-controlled rollout: metering mode records consumption without debiting a wallet. When enabled, generation reserves credits before submission and a refused submission releases that reservation. Accepted work retains its admission quote.
Hosted agent calls debit their observed token usage. A completed call can exceed its starting balance; the next call is then blocked. Missing provider counts remain marked incomplete. Cached input and reasoning output are already included in the provider's respective totals and are not added twice.
These starter credit ratios do not establish a currency price, subscription, automatic free allowance or purchase flow.